@raindrop-ai/deep-agents 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -56,6 +56,16 @@ await raindrop.shutdown();
56
56
  | `projectId` | `string` | - | Route events to a specific project (slug); omit for the default **Production** project |
57
57
  | `debug` | `boolean` | `false` | Enable verbose logging |
58
58
  | `traceChains` | `boolean` | `true` | Create spans for chain execution |
59
+ | `tools` | `ToolDeclaration[]` | - | Overrides the tool catalog recorded as `ai.prompt.tools` on every model span. Use when the integration cannot see the tools the model was given. |
60
+
61
+ ### Tool catalog capture
62
+
63
+ Every model span (`llm`) records the tools the agent's chat model was given for
64
+ that call as `ai.prompt.tools` (one JSON document per tool: `name`, `description`,
65
+ full JSON Schema as `inputSchema`). It is read from the callback's
66
+ `invocation_params.tools` / `functions`, which ChatOpenAI, ChatAnthropic and similar
67
+ models populate from `bindTools()`. Absent when the model reports no list; pass
68
+ `tools` to record a catalog explicitly (`tools: []` records an empty one).
59
69
 
60
70
  ## Projects
61
71
 
package/dist/index.d.mts CHANGED
@@ -509,6 +509,46 @@ declare global {
509
509
  var RAINDROP_ASYNC_LOCAL_STORAGE: (new <T>() => AsyncLocalStorageLike<T>) | undefined;
510
510
  }
511
511
 
512
+ /**
513
+ * `ai.prompt.tools`: the tool catalog a model call was given, one JSON
514
+ * document per tool, in the shape the Vercel AI SDK records on its
515
+ * `doGenerate` / `doStream` spans. Every integration emits this attribute on
516
+ * its model-call spans so downstream consumers (agent replay, world builder)
517
+ * can read what the model could call instead of guessing from the calls it
518
+ * happened to make.
519
+ *
520
+ * An absent attribute means the integration could not observe the tool list;
521
+ * an empty array means the model had no tools. Callers who know better than
522
+ * the integration pass a `tools` override, which replaces the inferred list.
523
+ */
524
+ declare const PROMPT_TOOLS_ATTRIBUTE = "ai.prompt.tools";
525
+ type JsonSchema = Record<string, unknown>;
526
+ type FunctionToolDeclaration = {
527
+ type: "function";
528
+ name: string;
529
+ description?: string;
530
+ inputSchema?: JsonSchema;
531
+ };
532
+ type ProviderDefinedToolDeclaration = {
533
+ type: "provider-defined";
534
+ id?: string;
535
+ name: string;
536
+ args?: Record<string, unknown>;
537
+ };
538
+ type ToolDeclaration = FunctionToolDeclaration | ProviderDefinedToolDeclaration;
539
+ /**
540
+ * What callers hand to a `tools` override. The canonical `ToolDeclaration`
541
+ * shape is accepted as-is; so is any framework shape `normalizeToolDeclarations`
542
+ * recognizes (OpenAI, Anthropic, Bedrock, LangChain, Pi, Mastra, AI SDK).
543
+ */
544
+ type ToolDeclarationInput = ToolDeclaration | {
545
+ name: string;
546
+ description?: string;
547
+ inputSchema?: JsonSchema;
548
+ parameters?: JsonSchema;
549
+ };
550
+ type PromptToolsOverride = ReadonlyArray<ToolDeclarationInput | unknown>;
551
+
512
552
  interface RaindropDeepAgentsHandlerOptions {
513
553
  eventShipper: EventShipper;
514
554
  traceShipper: TraceShipper;
@@ -526,6 +566,12 @@ interface RaindropDeepAgentsHandlerOptions {
526
566
  */
527
567
  maxTextFieldChars?: number;
528
568
  eventMaxTextFieldChars?: number;
569
+ /**
570
+ * Overrides the tool catalog recorded as `ai.prompt.tools` on every model
571
+ * span. Use when the integration cannot see the tools the model was given.
572
+ * Replaces the inferred list entirely; `[]` records an empty catalog.
573
+ */
574
+ tools?: PromptToolsOverride;
529
575
  }
530
576
  declare class RaindropDeepAgentsHandler extends BaseCallbackHandler {
531
577
  name: string;
@@ -538,6 +584,7 @@ declare class RaindropDeepAgentsHandler extends BaseCallbackHandler {
538
584
  private traceChains;
539
585
  private readonly configuredSpanMaxChars;
540
586
  private readonly eventMaxChars;
587
+ private readonly promptTools;
541
588
  private spans;
542
589
  private rootRunIds;
543
590
  private eventIds;
@@ -550,14 +597,15 @@ declare class RaindropDeepAgentsHandler extends BaseCallbackHandler {
550
597
  */
551
598
  _lastRootEventId: string | undefined;
552
599
  constructor(opts: RaindropDeepAgentsHandlerOptions);
600
+ private promptToolsAttribute;
553
601
  private get spanMaxChars();
554
602
  private getEventId;
555
603
  private getParent;
556
604
  private cleanup;
557
605
  private finalizeEventIfRoot;
558
606
  private rootErrorPatch;
559
- handleLLMStart(llm: Serialized, prompts: string[], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
560
- handleChatModelStart(llm: Serialized, messages: BaseMessage[][], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
607
+ handleLLMStart(llm: Serialized, prompts: string[], runId: string, parentRunId?: string, extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
608
+ handleChatModelStart(llm: Serialized, messages: BaseMessage[][], runId: string, parentRunId?: string, extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
561
609
  handleLLMEnd(output: LLMResult, runId: string, _parentRunId?: string): Promise<void>;
562
610
  handleLLMError(err: unknown, runId: string): Promise<void>;
563
611
  handleChainStart(chain: Serialized, _inputs: ChainValues, runId: string, parentRunId?: string, _tags?: string[], _metadata?: Record<string, unknown>, _runType?: string, runName?: string): Promise<void>;
@@ -610,6 +658,11 @@ interface DeepAgentsOptions {
610
658
  maxTextFieldChars?: number;
611
659
  /** Application Git identity. Auto-detects commit SHA by default; pass `false` to disable. */
612
660
  appGit?: AppGitOptions | false;
661
+ /**
662
+ * Overrides the tool catalog recorded as `ai.prompt.tools` on every model
663
+ * span. Use when the integration cannot see the tools the model was given.
664
+ */
665
+ tools?: PromptToolsOverride;
613
666
  }
614
667
  type RaindropDeepAgentsClient = {
615
668
  /**
@@ -697,4 +750,4 @@ type RaindropDeepAgentsClient = {
697
750
  */
698
751
  declare function createRaindropDeepAgents(opts: DeepAgentsOptions): RaindropDeepAgentsClient;
699
752
 
700
- export { type DeepAgentsOptions, type RaindropDeepAgentsClient, RaindropDeepAgentsHandler, createRaindropDeepAgents };
753
+ export { type DeepAgentsOptions, PROMPT_TOOLS_ATTRIBUTE, type PromptToolsOverride, type RaindropDeepAgentsClient, RaindropDeepAgentsHandler, type ToolDeclaration, createRaindropDeepAgents };
package/dist/index.d.ts CHANGED
@@ -509,6 +509,46 @@ declare global {
509
509
  var RAINDROP_ASYNC_LOCAL_STORAGE: (new <T>() => AsyncLocalStorageLike<T>) | undefined;
510
510
  }
511
511
 
512
+ /**
513
+ * `ai.prompt.tools`: the tool catalog a model call was given, one JSON
514
+ * document per tool, in the shape the Vercel AI SDK records on its
515
+ * `doGenerate` / `doStream` spans. Every integration emits this attribute on
516
+ * its model-call spans so downstream consumers (agent replay, world builder)
517
+ * can read what the model could call instead of guessing from the calls it
518
+ * happened to make.
519
+ *
520
+ * An absent attribute means the integration could not observe the tool list;
521
+ * an empty array means the model had no tools. Callers who know better than
522
+ * the integration pass a `tools` override, which replaces the inferred list.
523
+ */
524
+ declare const PROMPT_TOOLS_ATTRIBUTE = "ai.prompt.tools";
525
+ type JsonSchema = Record<string, unknown>;
526
+ type FunctionToolDeclaration = {
527
+ type: "function";
528
+ name: string;
529
+ description?: string;
530
+ inputSchema?: JsonSchema;
531
+ };
532
+ type ProviderDefinedToolDeclaration = {
533
+ type: "provider-defined";
534
+ id?: string;
535
+ name: string;
536
+ args?: Record<string, unknown>;
537
+ };
538
+ type ToolDeclaration = FunctionToolDeclaration | ProviderDefinedToolDeclaration;
539
+ /**
540
+ * What callers hand to a `tools` override. The canonical `ToolDeclaration`
541
+ * shape is accepted as-is; so is any framework shape `normalizeToolDeclarations`
542
+ * recognizes (OpenAI, Anthropic, Bedrock, LangChain, Pi, Mastra, AI SDK).
543
+ */
544
+ type ToolDeclarationInput = ToolDeclaration | {
545
+ name: string;
546
+ description?: string;
547
+ inputSchema?: JsonSchema;
548
+ parameters?: JsonSchema;
549
+ };
550
+ type PromptToolsOverride = ReadonlyArray<ToolDeclarationInput | unknown>;
551
+
512
552
  interface RaindropDeepAgentsHandlerOptions {
513
553
  eventShipper: EventShipper;
514
554
  traceShipper: TraceShipper;
@@ -526,6 +566,12 @@ interface RaindropDeepAgentsHandlerOptions {
526
566
  */
527
567
  maxTextFieldChars?: number;
528
568
  eventMaxTextFieldChars?: number;
569
+ /**
570
+ * Overrides the tool catalog recorded as `ai.prompt.tools` on every model
571
+ * span. Use when the integration cannot see the tools the model was given.
572
+ * Replaces the inferred list entirely; `[]` records an empty catalog.
573
+ */
574
+ tools?: PromptToolsOverride;
529
575
  }
530
576
  declare class RaindropDeepAgentsHandler extends BaseCallbackHandler {
531
577
  name: string;
@@ -538,6 +584,7 @@ declare class RaindropDeepAgentsHandler extends BaseCallbackHandler {
538
584
  private traceChains;
539
585
  private readonly configuredSpanMaxChars;
540
586
  private readonly eventMaxChars;
587
+ private readonly promptTools;
541
588
  private spans;
542
589
  private rootRunIds;
543
590
  private eventIds;
@@ -550,14 +597,15 @@ declare class RaindropDeepAgentsHandler extends BaseCallbackHandler {
550
597
  */
551
598
  _lastRootEventId: string | undefined;
552
599
  constructor(opts: RaindropDeepAgentsHandlerOptions);
600
+ private promptToolsAttribute;
553
601
  private get spanMaxChars();
554
602
  private getEventId;
555
603
  private getParent;
556
604
  private cleanup;
557
605
  private finalizeEventIfRoot;
558
606
  private rootErrorPatch;
559
- handleLLMStart(llm: Serialized, prompts: string[], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
560
- handleChatModelStart(llm: Serialized, messages: BaseMessage[][], runId: string, parentRunId?: string, _extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
607
+ handleLLMStart(llm: Serialized, prompts: string[], runId: string, parentRunId?: string, extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
608
+ handleChatModelStart(llm: Serialized, messages: BaseMessage[][], runId: string, parentRunId?: string, extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, runName?: string): Promise<void>;
561
609
  handleLLMEnd(output: LLMResult, runId: string, _parentRunId?: string): Promise<void>;
562
610
  handleLLMError(err: unknown, runId: string): Promise<void>;
563
611
  handleChainStart(chain: Serialized, _inputs: ChainValues, runId: string, parentRunId?: string, _tags?: string[], _metadata?: Record<string, unknown>, _runType?: string, runName?: string): Promise<void>;
@@ -610,6 +658,11 @@ interface DeepAgentsOptions {
610
658
  maxTextFieldChars?: number;
611
659
  /** Application Git identity. Auto-detects commit SHA by default; pass `false` to disable. */
612
660
  appGit?: AppGitOptions | false;
661
+ /**
662
+ * Overrides the tool catalog recorded as `ai.prompt.tools` on every model
663
+ * span. Use when the integration cannot see the tools the model was given.
664
+ */
665
+ tools?: PromptToolsOverride;
613
666
  }
614
667
  type RaindropDeepAgentsClient = {
615
668
  /**
@@ -697,4 +750,4 @@ type RaindropDeepAgentsClient = {
697
750
  */
698
751
  declare function createRaindropDeepAgents(opts: DeepAgentsOptions): RaindropDeepAgentsClient;
699
752
 
700
- export { type DeepAgentsOptions, type RaindropDeepAgentsClient, RaindropDeepAgentsHandler, createRaindropDeepAgents };
753
+ export { type DeepAgentsOptions, PROMPT_TOOLS_ATTRIBUTE, type PromptToolsOverride, type RaindropDeepAgentsClient, RaindropDeepAgentsHandler, type ToolDeclaration, createRaindropDeepAgents };
package/dist/index.js CHANGED
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ PROMPT_TOOLS_ATTRIBUTE: () => PROMPT_TOOLS_ATTRIBUTE,
23
24
  RaindropDeepAgentsHandler: () => RaindropDeepAgentsHandler,
24
25
  createRaindropDeepAgents: () => createRaindropDeepAgents
25
26
  });
@@ -90,7 +91,7 @@ function evalScopeAttributes() {
90
91
  return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
91
92
  }
92
93
 
93
- // ../core/dist/chunk-WJOR6M7H.js
94
+ // ../core/dist/chunk-I6TVJQEC.js
94
95
  var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
95
96
  function state() {
96
97
  const holder = globalThis;
@@ -2077,6 +2078,158 @@ var TraceShipper = class {
2077
2078
  }
2078
2079
  }
2079
2080
  };
2081
+ var PROMPT_TOOLS_ATTRIBUTE = "ai.prompt.tools";
2082
+ function isRecord(value) {
2083
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2084
+ }
2085
+ var JSON_SCHEMA_KEYS = [
2086
+ "type",
2087
+ "properties",
2088
+ "$schema",
2089
+ "$ref",
2090
+ "anyOf",
2091
+ "oneOf",
2092
+ "allOf",
2093
+ "enum",
2094
+ "const",
2095
+ "items",
2096
+ "additionalProperties",
2097
+ "required"
2098
+ ];
2099
+ function isJsonSchema(value) {
2100
+ if (!isRecord(value)) return false;
2101
+ if (typeof value["~standard"] === "object") return false;
2102
+ if (isRecord(value._def) || isRecord(value._zod)) return false;
2103
+ if (Object.keys(value).length === 0) return true;
2104
+ return JSON_SCHEMA_KEYS.some((key) => key in value);
2105
+ }
2106
+ function toJsonSchema(value, options) {
2107
+ if (value === void 0 || value === null) return void 0;
2108
+ if (isJsonSchema(value)) return value;
2109
+ if (isRecord(value) && isJsonSchema(value.jsonSchema)) return value.jsonSchema;
2110
+ if (isRecord(value) && isJsonSchema(value.json)) return value.json;
2111
+ if (options == null ? void 0 : options.schema) {
2112
+ try {
2113
+ return options.schema(value);
2114
+ } catch (e) {
2115
+ return void 0;
2116
+ }
2117
+ }
2118
+ return void 0;
2119
+ }
2120
+ function pickString(value) {
2121
+ return typeof value === "string" && value.length > 0 ? value : void 0;
2122
+ }
2123
+ function functionTool(name, description, schema, options) {
2124
+ const tool = { type: "function", name };
2125
+ const desc = pickString(description);
2126
+ if (desc !== void 0) tool.description = desc;
2127
+ const inputSchema = toJsonSchema(schema, options);
2128
+ if (inputSchema !== void 0) tool.inputSchema = inputSchema;
2129
+ return tool;
2130
+ }
2131
+ function normalizeToolDeclaration(tool, options, fallbackName) {
2132
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2133
+ if (!isRecord(tool)) return void 0;
2134
+ if (tool.type === "provider-defined" || tool.type === "provider") {
2135
+ const name2 = (_b = (_a = pickString(tool.name)) != null ? _a : pickString(tool.id)) != null ? _b : fallbackName;
2136
+ if (name2 === void 0) return void 0;
2137
+ const declaration = { type: "provider-defined", name: name2 };
2138
+ const id = pickString(tool.id);
2139
+ if (id !== void 0) declaration.id = id;
2140
+ if (isRecord(tool.args)) declaration.args = tool.args;
2141
+ return declaration;
2142
+ }
2143
+ if (isRecord(tool.toolSpec)) {
2144
+ const spec = tool.toolSpec;
2145
+ const name2 = (_c = pickString(spec.name)) != null ? _c : fallbackName;
2146
+ if (name2 === void 0) return void 0;
2147
+ return functionTool(name2, spec.description, spec.inputSchema, options);
2148
+ }
2149
+ if (isRecord(tool.function)) {
2150
+ const fn = tool.function;
2151
+ const name2 = (_d = pickString(fn.name)) != null ? _d : fallbackName;
2152
+ if (name2 === void 0) return void 0;
2153
+ return functionTool(name2, fn.description, (_e = fn.parameters) != null ? _e : fn.input_schema, options);
2154
+ }
2155
+ const name = (_g = (_f = pickString(tool.name)) != null ? _f : pickString(tool.id)) != null ? _g : fallbackName;
2156
+ if (name === void 0) return void 0;
2157
+ const type = pickString(tool.type);
2158
+ if (type !== void 0 && type !== "function" && type !== "dynamic" && type !== "custom") {
2159
+ if (!("input_schema" in tool) && !("inputSchema" in tool) && !("parameters" in tool)) {
2160
+ return { type: "provider-defined", id: type, name };
2161
+ }
2162
+ }
2163
+ return functionTool(
2164
+ name,
2165
+ tool.description,
2166
+ (_j = (_i = (_h = tool.inputSchema) != null ? _h : tool.input_schema) != null ? _i : tool.parameters) != null ? _j : tool.schema,
2167
+ options
2168
+ );
2169
+ }
2170
+ var NOT_A_GEMINI_GROUP_KEYS = ["name", "id", "type", "function", "toolSpec", "cachePoint"];
2171
+ function isGeminiToolGroup(tool) {
2172
+ if (Array.isArray(tool.functionDeclarations)) return true;
2173
+ const keys = Object.keys(tool);
2174
+ if (keys.length === 0 || NOT_A_GEMINI_GROUP_KEYS.some((key) => key in tool)) return false;
2175
+ return keys.every((key) => isRecord(tool[key]));
2176
+ }
2177
+ function expandGeminiTool(tool, options) {
2178
+ const declarations = [];
2179
+ for (const [key, value] of Object.entries(tool)) {
2180
+ if (key === "functionDeclarations" && Array.isArray(value)) {
2181
+ for (const declaration of value) {
2182
+ const normalized = normalizeToolDeclaration(declaration, options);
2183
+ if (normalized) declarations.push(normalized);
2184
+ }
2185
+ } else if (isRecord(value)) {
2186
+ declarations.push({ type: "provider-defined", id: key, name: key, args: value });
2187
+ }
2188
+ }
2189
+ return declarations;
2190
+ }
2191
+ function normalizeToolDeclarations(tools, options) {
2192
+ if (tools === void 0 || tools === null) return void 0;
2193
+ if (Array.isArray(tools)) {
2194
+ return tools.flatMap((tool) => {
2195
+ if (isRecord(tool) && isGeminiToolGroup(tool)) {
2196
+ return expandGeminiTool(tool, options);
2197
+ }
2198
+ const declaration = normalizeToolDeclaration(tool, options);
2199
+ return declaration ? [declaration] : [];
2200
+ });
2201
+ }
2202
+ if (!isRecord(tools)) return void 0;
2203
+ return Object.entries(tools).flatMap(([key, tool]) => {
2204
+ const declaration = normalizeToolDeclaration(tool, options, key);
2205
+ return declaration ? [declaration] : [];
2206
+ });
2207
+ }
2208
+ function resolvePromptTools(args) {
2209
+ var _a;
2210
+ if (args.override !== void 0) {
2211
+ return (_a = normalizeToolDeclarations(args.override, args.options)) != null ? _a : [];
2212
+ }
2213
+ return normalizeToolDeclarations(args.inferred, args.options);
2214
+ }
2215
+ function promptToolsAttribute(tools) {
2216
+ const values = promptToolsAttributeValue(tools);
2217
+ if (values === void 0) return void 0;
2218
+ return {
2219
+ key: PROMPT_TOOLS_ATTRIBUTE,
2220
+ value: { arrayValue: { values: values.map((stringValue) => ({ stringValue })) } }
2221
+ };
2222
+ }
2223
+ function promptToolsAttributeValue(tools) {
2224
+ if (tools === void 0) return void 0;
2225
+ return tools.map((tool) => {
2226
+ try {
2227
+ return JSON.stringify(tool);
2228
+ } catch (e) {
2229
+ return JSON.stringify({ type: tool.type, name: tool.name });
2230
+ }
2231
+ });
2232
+ }
2080
2233
 
2081
2234
  // ../core/dist/index.node.js
2082
2235
  var import_async_hooks = require("async_hooks");
@@ -2391,7 +2544,7 @@ var CAPTURE_TRUNCATED_ROLE = "raindrop";
2391
2544
  var MESSAGE_OVERHEAD = 32;
2392
2545
  var PART_OVERHEAD = 24;
2393
2546
  var MAX_DEPTH2 = 12;
2394
- function isRecord(value) {
2547
+ function isRecord2(value) {
2395
2548
  return typeof value === "object" && value !== null && !Array.isArray(value);
2396
2549
  }
2397
2550
  function stringField(record, key) {
@@ -2445,7 +2598,7 @@ function takeValue(value, budget, depth) {
2445
2598
  }
2446
2599
  budget.remaining -= 2;
2447
2600
  const out = {};
2448
- if (!isRecord(value)) return out;
2601
+ if (!isRecord2(value)) return out;
2449
2602
  for (const key in value) {
2450
2603
  if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
2451
2604
  if (budget.remaining <= 0) {
@@ -2473,7 +2626,7 @@ function joinedText(content, budget) {
2473
2626
  break;
2474
2627
  }
2475
2628
  budget.remaining -= 1;
2476
- if (!isRecord(block)) continue;
2629
+ if (!isRecord2(block)) continue;
2477
2630
  const text = stringField(block, "text");
2478
2631
  if (text !== void 0) texts.push(takeText(text, budget));
2479
2632
  }
@@ -2481,13 +2634,13 @@ function joinedText(content, budget) {
2481
2634
  }
2482
2635
  function contentPart(block, budget) {
2483
2636
  budget.remaining -= PART_OVERHEAD;
2484
- if (!isRecord(block)) return takeValue(block, budget, 0);
2637
+ if (!isRecord2(block)) return takeValue(block, budget, 0);
2485
2638
  const type = stringField(block, "type");
2486
2639
  const text = stringField(block, "text");
2487
2640
  if (type === "text" && text !== void 0) return textPart(text, budget);
2488
2641
  if (type === "image_url") {
2489
2642
  const imageUrl = block["image_url"];
2490
- const url = typeof imageUrl === "string" ? imageUrl : isRecord(imageUrl) ? stringField(imageUrl, "url") : void 0;
2643
+ const url = typeof imageUrl === "string" ? imageUrl : isRecord2(imageUrl) ? stringField(imageUrl, "url") : void 0;
2491
2644
  if (url !== void 0) return { type: "image", image: takeText(url, budget) };
2492
2645
  }
2493
2646
  if (type === "thinking") {
@@ -2499,8 +2652,8 @@ function contentPart(block, budget) {
2499
2652
  const sourceType = stringField(block, "source_type");
2500
2653
  const source = block["source"];
2501
2654
  if (sourceType === "text" && text !== void 0) return textPart(text, budget);
2502
- const data = sourceType === "url" ? stringField(block, "url") : sourceType === "base64" ? stringField(block, "data") : isRecord(source) ? stringField(source, "url") ?? stringField(source, "data") : void 0;
2503
- const sourceMediaType = mediaType ?? (isRecord(source) ? stringField(source, "media_type") : void 0);
2655
+ const data = sourceType === "url" ? stringField(block, "url") : sourceType === "base64" ? stringField(block, "data") : isRecord2(source) ? stringField(source, "url") ?? stringField(source, "data") : void 0;
2656
+ const sourceMediaType = mediaType ?? (isRecord2(source) ? stringField(source, "media_type") : void 0);
2504
2657
  if (data !== void 0) {
2505
2658
  const filename = stringField(block, "filename");
2506
2659
  return type === "image" ? { type: "image", image: takeText(data, budget), mediaType: reserve(sourceMediaType, budget) } : {
@@ -2521,7 +2674,7 @@ function contentParts(content, budget, skipToolUseIds) {
2521
2674
  parts.push({ type: "text", text: TRUNCATION_MARKER2 });
2522
2675
  break;
2523
2676
  }
2524
- if (isRecord(block) && (block["type"] === "tool_use" || block["type"] === "tool_call")) {
2677
+ if (isRecord2(block) && (block["type"] === "tool_use" || block["type"] === "tool_call")) {
2525
2678
  const id = stringField(block, "id");
2526
2679
  if (id !== void 0 && skipToolUseIds.has(id)) continue;
2527
2680
  }
@@ -2664,12 +2817,12 @@ function capturePrompt(prompt, limit) {
2664
2817
  }
2665
2818
  }
2666
2819
  function captureToolCalls(message, limit) {
2667
- if (!isRecord(message) || !Array.isArray(message["tool_calls"])) return void 0;
2820
+ if (!isRecord2(message) || !Array.isArray(message["tool_calls"])) return void 0;
2668
2821
  const calls = [];
2669
2822
  let structural = 0;
2670
2823
  for (const call of message["tool_calls"]) {
2671
2824
  structural += PART_OVERHEAD;
2672
- if (isRecord(call)) {
2825
+ if (isRecord2(call)) {
2673
2826
  structural += (stringField(call, "id")?.length ?? 0) + (stringField(call, "name")?.length ?? 0);
2674
2827
  calls.push(call);
2675
2828
  }
@@ -2692,7 +2845,7 @@ function captureToolCalls(message, limit) {
2692
2845
  function parseToolCallInput(input) {
2693
2846
  try {
2694
2847
  const parsed = JSON.parse(input);
2695
- if (isRecord(parsed) && parsed["type"] === "tool_call" && "args" in parsed) {
2848
+ if (isRecord2(parsed) && parsed["type"] === "tool_call" && "args" in parsed) {
2696
2849
  return { id: stringField(parsed, "id"), args: JSON.stringify(parsed["args"]) };
2697
2850
  }
2698
2851
  } catch {
@@ -2710,6 +2863,12 @@ function unwrapToolOutput(output) {
2710
2863
  }
2711
2864
 
2712
2865
  // src/callback-handler.ts
2866
+ function inferInvocationTools(extraParams) {
2867
+ const params = extraParams?.invocation_params;
2868
+ if (typeof params !== "object" || params === null) return void 0;
2869
+ const record = { ...params };
2870
+ return record.tools ?? record.functions;
2871
+ }
2713
2872
  function resolveEventId(source) {
2714
2873
  if (typeof source !== "function") return randomUUID();
2715
2874
  try {
@@ -2778,6 +2937,12 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
2778
2937
  this.traceChains = opts.traceChains ?? true;
2779
2938
  this.configuredSpanMaxChars = opts.maxTextFieldChars ?? eventMaxTextFieldChars();
2780
2939
  this.eventMaxChars = opts.eventMaxTextFieldChars ?? eventMaxTextFieldChars();
2940
+ this.promptTools = opts.tools;
2941
+ }
2942
+ promptToolsAttribute(extraParams) {
2943
+ return promptToolsAttribute(
2944
+ resolvePromptTools({ override: this.promptTools, inferred: inferInvocationTools(extraParams) })
2945
+ );
2781
2946
  }
2782
2947
  get spanMaxChars() {
2783
2948
  return spanAttributeLimit(this.configuredSpanMaxChars);
@@ -2841,7 +3006,7 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
2841
3006
  // ---------------------------------------------------------------------------
2842
3007
  // LLM events
2843
3008
  // ---------------------------------------------------------------------------
2844
- async handleLLMStart(llm, prompts, runId, parentRunId, _extraParams, tags, metadata, runName) {
3009
+ async handleLLMStart(llm, prompts, runId, parentRunId, extraParams, tags, metadata, runName) {
2845
3010
  try {
2846
3011
  if (this.spans.has(runId)) return;
2847
3012
  const eventId = this.getEventId(runId, parentRunId);
@@ -2860,7 +3025,8 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
2860
3025
  attributes: [
2861
3026
  attrString("ai.model.provider", modelId),
2862
3027
  attrString("ai.operationId", "ai.generateText"),
2863
- ...promptAttributes(capturePrompt(prompt, this.spanMaxChars))
3028
+ ...promptAttributes(capturePrompt(prompt, this.spanMaxChars)),
3029
+ this.promptToolsAttribute(extraParams)
2864
3030
  ]
2865
3031
  });
2866
3032
  this.spans.set(runId, span);
@@ -2875,7 +3041,7 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
2875
3041
  } catch {
2876
3042
  }
2877
3043
  }
2878
- async handleChatModelStart(llm, messages, runId, parentRunId, _extraParams, tags, metadata, runName) {
3044
+ async handleChatModelStart(llm, messages, runId, parentRunId, extraParams, tags, metadata, runName) {
2879
3045
  try {
2880
3046
  if (this.spans.has(runId)) return;
2881
3047
  const eventId = this.getEventId(runId, parentRunId);
@@ -2894,7 +3060,8 @@ var RaindropDeepAgentsHandler = class extends import_base.BaseCallbackHandler {
2894
3060
  attributes: [
2895
3061
  attrString("ai.model.provider", modelId),
2896
3062
  attrString("ai.operationId", "ai.generateText"),
2897
- ...promptAttributes(captureConversation(conversation, this.spanMaxChars))
3063
+ ...promptAttributes(captureConversation(conversation, this.spanMaxChars)),
3064
+ this.promptToolsAttribute(extraParams)
2898
3065
  ]
2899
3066
  });
2900
3067
  this.spans.set(runId, span);
@@ -3210,7 +3377,7 @@ function asNumber(val) {
3210
3377
  // package.json
3211
3378
  var package_default = {
3212
3379
  name: "@raindrop-ai/deep-agents",
3213
- version: "0.1.3",
3380
+ version: "0.1.4",
3214
3381
  description: "Raindrop integration for LangChain Deep Agents",
3215
3382
  main: "dist/index.js",
3216
3383
  module: "dist/index.mjs",
@@ -3324,7 +3491,8 @@ function createRaindropDeepAgents(opts) {
3324
3491
  eventId: opts.eventId,
3325
3492
  traceChains: opts.traceChains,
3326
3493
  maxTextFieldChars: maxChars,
3327
- eventMaxTextFieldChars: maxChars
3494
+ eventMaxTextFieldChars: maxChars,
3495
+ tools: opts.tools
3328
3496
  });
3329
3497
  return {
3330
3498
  handler,
@@ -3372,6 +3540,7 @@ function createRaindropDeepAgents(opts) {
3372
3540
  }
3373
3541
  // Annotate the CommonJS export names for ESM import in node:
3374
3542
  0 && (module.exports = {
3543
+ PROMPT_TOOLS_ATTRIBUTE,
3375
3544
  RaindropDeepAgentsHandler,
3376
3545
  createRaindropDeepAgents
3377
3546
  });
package/dist/index.mjs CHANGED
@@ -63,7 +63,7 @@ function evalScopeAttributes() {
63
63
  return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
64
64
  }
65
65
 
66
- // ../core/dist/chunk-WJOR6M7H.js
66
+ // ../core/dist/chunk-I6TVJQEC.js
67
67
  var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
68
68
  function state() {
69
69
  const holder = globalThis;
@@ -2050,6 +2050,158 @@ var TraceShipper = class {
2050
2050
  }
2051
2051
  }
2052
2052
  };
2053
+ var PROMPT_TOOLS_ATTRIBUTE = "ai.prompt.tools";
2054
+ function isRecord(value) {
2055
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2056
+ }
2057
+ var JSON_SCHEMA_KEYS = [
2058
+ "type",
2059
+ "properties",
2060
+ "$schema",
2061
+ "$ref",
2062
+ "anyOf",
2063
+ "oneOf",
2064
+ "allOf",
2065
+ "enum",
2066
+ "const",
2067
+ "items",
2068
+ "additionalProperties",
2069
+ "required"
2070
+ ];
2071
+ function isJsonSchema(value) {
2072
+ if (!isRecord(value)) return false;
2073
+ if (typeof value["~standard"] === "object") return false;
2074
+ if (isRecord(value._def) || isRecord(value._zod)) return false;
2075
+ if (Object.keys(value).length === 0) return true;
2076
+ return JSON_SCHEMA_KEYS.some((key) => key in value);
2077
+ }
2078
+ function toJsonSchema(value, options) {
2079
+ if (value === void 0 || value === null) return void 0;
2080
+ if (isJsonSchema(value)) return value;
2081
+ if (isRecord(value) && isJsonSchema(value.jsonSchema)) return value.jsonSchema;
2082
+ if (isRecord(value) && isJsonSchema(value.json)) return value.json;
2083
+ if (options == null ? void 0 : options.schema) {
2084
+ try {
2085
+ return options.schema(value);
2086
+ } catch (e) {
2087
+ return void 0;
2088
+ }
2089
+ }
2090
+ return void 0;
2091
+ }
2092
+ function pickString(value) {
2093
+ return typeof value === "string" && value.length > 0 ? value : void 0;
2094
+ }
2095
+ function functionTool(name, description, schema, options) {
2096
+ const tool = { type: "function", name };
2097
+ const desc = pickString(description);
2098
+ if (desc !== void 0) tool.description = desc;
2099
+ const inputSchema = toJsonSchema(schema, options);
2100
+ if (inputSchema !== void 0) tool.inputSchema = inputSchema;
2101
+ return tool;
2102
+ }
2103
+ function normalizeToolDeclaration(tool, options, fallbackName) {
2104
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2105
+ if (!isRecord(tool)) return void 0;
2106
+ if (tool.type === "provider-defined" || tool.type === "provider") {
2107
+ const name2 = (_b = (_a = pickString(tool.name)) != null ? _a : pickString(tool.id)) != null ? _b : fallbackName;
2108
+ if (name2 === void 0) return void 0;
2109
+ const declaration = { type: "provider-defined", name: name2 };
2110
+ const id = pickString(tool.id);
2111
+ if (id !== void 0) declaration.id = id;
2112
+ if (isRecord(tool.args)) declaration.args = tool.args;
2113
+ return declaration;
2114
+ }
2115
+ if (isRecord(tool.toolSpec)) {
2116
+ const spec = tool.toolSpec;
2117
+ const name2 = (_c = pickString(spec.name)) != null ? _c : fallbackName;
2118
+ if (name2 === void 0) return void 0;
2119
+ return functionTool(name2, spec.description, spec.inputSchema, options);
2120
+ }
2121
+ if (isRecord(tool.function)) {
2122
+ const fn = tool.function;
2123
+ const name2 = (_d = pickString(fn.name)) != null ? _d : fallbackName;
2124
+ if (name2 === void 0) return void 0;
2125
+ return functionTool(name2, fn.description, (_e = fn.parameters) != null ? _e : fn.input_schema, options);
2126
+ }
2127
+ const name = (_g = (_f = pickString(tool.name)) != null ? _f : pickString(tool.id)) != null ? _g : fallbackName;
2128
+ if (name === void 0) return void 0;
2129
+ const type = pickString(tool.type);
2130
+ if (type !== void 0 && type !== "function" && type !== "dynamic" && type !== "custom") {
2131
+ if (!("input_schema" in tool) && !("inputSchema" in tool) && !("parameters" in tool)) {
2132
+ return { type: "provider-defined", id: type, name };
2133
+ }
2134
+ }
2135
+ return functionTool(
2136
+ name,
2137
+ tool.description,
2138
+ (_j = (_i = (_h = tool.inputSchema) != null ? _h : tool.input_schema) != null ? _i : tool.parameters) != null ? _j : tool.schema,
2139
+ options
2140
+ );
2141
+ }
2142
+ var NOT_A_GEMINI_GROUP_KEYS = ["name", "id", "type", "function", "toolSpec", "cachePoint"];
2143
+ function isGeminiToolGroup(tool) {
2144
+ if (Array.isArray(tool.functionDeclarations)) return true;
2145
+ const keys = Object.keys(tool);
2146
+ if (keys.length === 0 || NOT_A_GEMINI_GROUP_KEYS.some((key) => key in tool)) return false;
2147
+ return keys.every((key) => isRecord(tool[key]));
2148
+ }
2149
+ function expandGeminiTool(tool, options) {
2150
+ const declarations = [];
2151
+ for (const [key, value] of Object.entries(tool)) {
2152
+ if (key === "functionDeclarations" && Array.isArray(value)) {
2153
+ for (const declaration of value) {
2154
+ const normalized = normalizeToolDeclaration(declaration, options);
2155
+ if (normalized) declarations.push(normalized);
2156
+ }
2157
+ } else if (isRecord(value)) {
2158
+ declarations.push({ type: "provider-defined", id: key, name: key, args: value });
2159
+ }
2160
+ }
2161
+ return declarations;
2162
+ }
2163
+ function normalizeToolDeclarations(tools, options) {
2164
+ if (tools === void 0 || tools === null) return void 0;
2165
+ if (Array.isArray(tools)) {
2166
+ return tools.flatMap((tool) => {
2167
+ if (isRecord(tool) && isGeminiToolGroup(tool)) {
2168
+ return expandGeminiTool(tool, options);
2169
+ }
2170
+ const declaration = normalizeToolDeclaration(tool, options);
2171
+ return declaration ? [declaration] : [];
2172
+ });
2173
+ }
2174
+ if (!isRecord(tools)) return void 0;
2175
+ return Object.entries(tools).flatMap(([key, tool]) => {
2176
+ const declaration = normalizeToolDeclaration(tool, options, key);
2177
+ return declaration ? [declaration] : [];
2178
+ });
2179
+ }
2180
+ function resolvePromptTools(args) {
2181
+ var _a;
2182
+ if (args.override !== void 0) {
2183
+ return (_a = normalizeToolDeclarations(args.override, args.options)) != null ? _a : [];
2184
+ }
2185
+ return normalizeToolDeclarations(args.inferred, args.options);
2186
+ }
2187
+ function promptToolsAttribute(tools) {
2188
+ const values = promptToolsAttributeValue(tools);
2189
+ if (values === void 0) return void 0;
2190
+ return {
2191
+ key: PROMPT_TOOLS_ATTRIBUTE,
2192
+ value: { arrayValue: { values: values.map((stringValue) => ({ stringValue })) } }
2193
+ };
2194
+ }
2195
+ function promptToolsAttributeValue(tools) {
2196
+ if (tools === void 0) return void 0;
2197
+ return tools.map((tool) => {
2198
+ try {
2199
+ return JSON.stringify(tool);
2200
+ } catch (e) {
2201
+ return JSON.stringify({ type: tool.type, name: tool.name });
2202
+ }
2203
+ });
2204
+ }
2053
2205
 
2054
2206
  // ../core/dist/index.node.js
2055
2207
  import { AsyncLocalStorage } from "async_hooks";
@@ -2369,7 +2521,7 @@ var CAPTURE_TRUNCATED_ROLE = "raindrop";
2369
2521
  var MESSAGE_OVERHEAD = 32;
2370
2522
  var PART_OVERHEAD = 24;
2371
2523
  var MAX_DEPTH2 = 12;
2372
- function isRecord(value) {
2524
+ function isRecord2(value) {
2373
2525
  return typeof value === "object" && value !== null && !Array.isArray(value);
2374
2526
  }
2375
2527
  function stringField(record, key) {
@@ -2423,7 +2575,7 @@ function takeValue(value, budget, depth) {
2423
2575
  }
2424
2576
  budget.remaining -= 2;
2425
2577
  const out = {};
2426
- if (!isRecord(value)) return out;
2578
+ if (!isRecord2(value)) return out;
2427
2579
  for (const key in value) {
2428
2580
  if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
2429
2581
  if (budget.remaining <= 0) {
@@ -2451,7 +2603,7 @@ function joinedText(content, budget) {
2451
2603
  break;
2452
2604
  }
2453
2605
  budget.remaining -= 1;
2454
- if (!isRecord(block)) continue;
2606
+ if (!isRecord2(block)) continue;
2455
2607
  const text = stringField(block, "text");
2456
2608
  if (text !== void 0) texts.push(takeText(text, budget));
2457
2609
  }
@@ -2459,13 +2611,13 @@ function joinedText(content, budget) {
2459
2611
  }
2460
2612
  function contentPart(block, budget) {
2461
2613
  budget.remaining -= PART_OVERHEAD;
2462
- if (!isRecord(block)) return takeValue(block, budget, 0);
2614
+ if (!isRecord2(block)) return takeValue(block, budget, 0);
2463
2615
  const type = stringField(block, "type");
2464
2616
  const text = stringField(block, "text");
2465
2617
  if (type === "text" && text !== void 0) return textPart(text, budget);
2466
2618
  if (type === "image_url") {
2467
2619
  const imageUrl = block["image_url"];
2468
- const url = typeof imageUrl === "string" ? imageUrl : isRecord(imageUrl) ? stringField(imageUrl, "url") : void 0;
2620
+ const url = typeof imageUrl === "string" ? imageUrl : isRecord2(imageUrl) ? stringField(imageUrl, "url") : void 0;
2469
2621
  if (url !== void 0) return { type: "image", image: takeText(url, budget) };
2470
2622
  }
2471
2623
  if (type === "thinking") {
@@ -2477,8 +2629,8 @@ function contentPart(block, budget) {
2477
2629
  const sourceType = stringField(block, "source_type");
2478
2630
  const source = block["source"];
2479
2631
  if (sourceType === "text" && text !== void 0) return textPart(text, budget);
2480
- const data = sourceType === "url" ? stringField(block, "url") : sourceType === "base64" ? stringField(block, "data") : isRecord(source) ? stringField(source, "url") ?? stringField(source, "data") : void 0;
2481
- const sourceMediaType = mediaType ?? (isRecord(source) ? stringField(source, "media_type") : void 0);
2632
+ const data = sourceType === "url" ? stringField(block, "url") : sourceType === "base64" ? stringField(block, "data") : isRecord2(source) ? stringField(source, "url") ?? stringField(source, "data") : void 0;
2633
+ const sourceMediaType = mediaType ?? (isRecord2(source) ? stringField(source, "media_type") : void 0);
2482
2634
  if (data !== void 0) {
2483
2635
  const filename = stringField(block, "filename");
2484
2636
  return type === "image" ? { type: "image", image: takeText(data, budget), mediaType: reserve(sourceMediaType, budget) } : {
@@ -2499,7 +2651,7 @@ function contentParts(content, budget, skipToolUseIds) {
2499
2651
  parts.push({ type: "text", text: TRUNCATION_MARKER2 });
2500
2652
  break;
2501
2653
  }
2502
- if (isRecord(block) && (block["type"] === "tool_use" || block["type"] === "tool_call")) {
2654
+ if (isRecord2(block) && (block["type"] === "tool_use" || block["type"] === "tool_call")) {
2503
2655
  const id = stringField(block, "id");
2504
2656
  if (id !== void 0 && skipToolUseIds.has(id)) continue;
2505
2657
  }
@@ -2642,12 +2794,12 @@ function capturePrompt(prompt, limit) {
2642
2794
  }
2643
2795
  }
2644
2796
  function captureToolCalls(message, limit) {
2645
- if (!isRecord(message) || !Array.isArray(message["tool_calls"])) return void 0;
2797
+ if (!isRecord2(message) || !Array.isArray(message["tool_calls"])) return void 0;
2646
2798
  const calls = [];
2647
2799
  let structural = 0;
2648
2800
  for (const call of message["tool_calls"]) {
2649
2801
  structural += PART_OVERHEAD;
2650
- if (isRecord(call)) {
2802
+ if (isRecord2(call)) {
2651
2803
  structural += (stringField(call, "id")?.length ?? 0) + (stringField(call, "name")?.length ?? 0);
2652
2804
  calls.push(call);
2653
2805
  }
@@ -2670,7 +2822,7 @@ function captureToolCalls(message, limit) {
2670
2822
  function parseToolCallInput(input) {
2671
2823
  try {
2672
2824
  const parsed = JSON.parse(input);
2673
- if (isRecord(parsed) && parsed["type"] === "tool_call" && "args" in parsed) {
2825
+ if (isRecord2(parsed) && parsed["type"] === "tool_call" && "args" in parsed) {
2674
2826
  return { id: stringField(parsed, "id"), args: JSON.stringify(parsed["args"]) };
2675
2827
  }
2676
2828
  } catch {
@@ -2688,6 +2840,12 @@ function unwrapToolOutput(output) {
2688
2840
  }
2689
2841
 
2690
2842
  // src/callback-handler.ts
2843
+ function inferInvocationTools(extraParams) {
2844
+ const params = extraParams?.invocation_params;
2845
+ if (typeof params !== "object" || params === null) return void 0;
2846
+ const record = { ...params };
2847
+ return record.tools ?? record.functions;
2848
+ }
2691
2849
  function resolveEventId(source) {
2692
2850
  if (typeof source !== "function") return randomUUID();
2693
2851
  try {
@@ -2756,6 +2914,12 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
2756
2914
  this.traceChains = opts.traceChains ?? true;
2757
2915
  this.configuredSpanMaxChars = opts.maxTextFieldChars ?? eventMaxTextFieldChars();
2758
2916
  this.eventMaxChars = opts.eventMaxTextFieldChars ?? eventMaxTextFieldChars();
2917
+ this.promptTools = opts.tools;
2918
+ }
2919
+ promptToolsAttribute(extraParams) {
2920
+ return promptToolsAttribute(
2921
+ resolvePromptTools({ override: this.promptTools, inferred: inferInvocationTools(extraParams) })
2922
+ );
2759
2923
  }
2760
2924
  get spanMaxChars() {
2761
2925
  return spanAttributeLimit(this.configuredSpanMaxChars);
@@ -2819,7 +2983,7 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
2819
2983
  // ---------------------------------------------------------------------------
2820
2984
  // LLM events
2821
2985
  // ---------------------------------------------------------------------------
2822
- async handleLLMStart(llm, prompts, runId, parentRunId, _extraParams, tags, metadata, runName) {
2986
+ async handleLLMStart(llm, prompts, runId, parentRunId, extraParams, tags, metadata, runName) {
2823
2987
  try {
2824
2988
  if (this.spans.has(runId)) return;
2825
2989
  const eventId = this.getEventId(runId, parentRunId);
@@ -2838,7 +3002,8 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
2838
3002
  attributes: [
2839
3003
  attrString("ai.model.provider", modelId),
2840
3004
  attrString("ai.operationId", "ai.generateText"),
2841
- ...promptAttributes(capturePrompt(prompt, this.spanMaxChars))
3005
+ ...promptAttributes(capturePrompt(prompt, this.spanMaxChars)),
3006
+ this.promptToolsAttribute(extraParams)
2842
3007
  ]
2843
3008
  });
2844
3009
  this.spans.set(runId, span);
@@ -2853,7 +3018,7 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
2853
3018
  } catch {
2854
3019
  }
2855
3020
  }
2856
- async handleChatModelStart(llm, messages, runId, parentRunId, _extraParams, tags, metadata, runName) {
3021
+ async handleChatModelStart(llm, messages, runId, parentRunId, extraParams, tags, metadata, runName) {
2857
3022
  try {
2858
3023
  if (this.spans.has(runId)) return;
2859
3024
  const eventId = this.getEventId(runId, parentRunId);
@@ -2872,7 +3037,8 @@ var RaindropDeepAgentsHandler = class extends BaseCallbackHandler {
2872
3037
  attributes: [
2873
3038
  attrString("ai.model.provider", modelId),
2874
3039
  attrString("ai.operationId", "ai.generateText"),
2875
- ...promptAttributes(captureConversation(conversation, this.spanMaxChars))
3040
+ ...promptAttributes(captureConversation(conversation, this.spanMaxChars)),
3041
+ this.promptToolsAttribute(extraParams)
2876
3042
  ]
2877
3043
  });
2878
3044
  this.spans.set(runId, span);
@@ -3188,7 +3354,7 @@ function asNumber(val) {
3188
3354
  // package.json
3189
3355
  var package_default = {
3190
3356
  name: "@raindrop-ai/deep-agents",
3191
- version: "0.1.3",
3357
+ version: "0.1.4",
3192
3358
  description: "Raindrop integration for LangChain Deep Agents",
3193
3359
  main: "dist/index.js",
3194
3360
  module: "dist/index.mjs",
@@ -3302,7 +3468,8 @@ function createRaindropDeepAgents(opts) {
3302
3468
  eventId: opts.eventId,
3303
3469
  traceChains: opts.traceChains,
3304
3470
  maxTextFieldChars: maxChars,
3305
- eventMaxTextFieldChars: maxChars
3471
+ eventMaxTextFieldChars: maxChars,
3472
+ tools: opts.tools
3306
3473
  });
3307
3474
  return {
3308
3475
  handler,
@@ -3349,6 +3516,7 @@ function createRaindropDeepAgents(opts) {
3349
3516
  };
3350
3517
  }
3351
3518
  export {
3519
+ PROMPT_TOOLS_ATTRIBUTE,
3352
3520
  RaindropDeepAgentsHandler,
3353
3521
  createRaindropDeepAgents
3354
3522
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raindrop-ai/deep-agents",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Raindrop integration for LangChain Deep Agents",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -36,7 +36,7 @@
36
36
  "typescript": "^5.3.3",
37
37
  "vitest": "^2.1.9",
38
38
  "zod": "^3.23.0",
39
- "@raindrop-ai/core": "0.3.0"
39
+ "@raindrop-ai/core": "0.3.1"
40
40
  },
41
41
  "tsup": {
42
42
  "entry": [