@raindrop-ai/openai-managed-agents 0.0.2 → 0.0.3

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
@@ -120,6 +120,27 @@ responsibility.
120
120
  `users.identify`, and `signals.track` expose the shared core enrichment API.
121
121
  `flush()` ships current buffers; `shutdown()` also closes unfinished captures.
122
122
 
123
+ ## Tool catalog capture (`ai.prompt.tools`)
124
+
125
+ **Agent configuration, not exact per-call capture.** Model calls run inside
126
+ OpenAI's managed runtime, so the wrapper never sees individual requests. It
127
+ does see the resolved agent definition on the session (`session.agent.tools`)
128
+ and records it as `ai.prompt.tools` on every coordinator `openai.agent.turn`
129
+ span (one per model turn), together with
130
+ `ai.prompt.tools.source = "agent.config"` so consumers can tell this
131
+ configuration snapshot from exact capture. Function tools keep their JSON
132
+ Schema `parameters`; `mcp`, `web_search`, `tool_search` and
133
+ `programmatic_tool_calling` entries are provider-owned and recorded as
134
+ `{"type":"provider-defined",…}` without an invented schema. Subagent turns run
135
+ their own tool sets, so they only receive an explicit override. Absent
136
+ attribute = catalog unknown; `[]` = the agent has no tools. This package has no
137
+ separate prompt-content switch, so the attribute is recorded whenever tracing
138
+ is enabled.
139
+
140
+ | Option | Description |
141
+ | --- | --- |
142
+ | `tools` (on `createRaindropOpenAIManagedAgents({ tools })` or `wrap(client, { tools })`) | 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. Replaces the agent definition entirely (`tools: []` records an empty catalog) and carries no `source` attribute. |
143
+
123
144
  ## Limits
124
145
 
125
146
  The service does not expose individual inference requests. Captures represent
package/dist/index.d.mts CHANGED
@@ -506,9 +506,42 @@ declare global {
506
506
  var RAINDROP_CONTEXT_MANAGER: (new () => ContextManager) | undefined;
507
507
  var RAINDROP_ASYNC_LOCAL_STORAGE: (new <T>() => AsyncLocalStorageLike<T>) | undefined;
508
508
  }
509
+ type JsonSchema = Record<string, unknown>;
510
+ type FunctionToolDeclaration = {
511
+ type: "function";
512
+ name: string;
513
+ description?: string;
514
+ inputSchema?: JsonSchema;
515
+ };
516
+ type ProviderDefinedToolDeclaration = {
517
+ type: "provider-defined";
518
+ id?: string;
519
+ name: string;
520
+ args?: Record<string, unknown>;
521
+ };
522
+ type ToolDeclaration = FunctionToolDeclaration | ProviderDefinedToolDeclaration;
523
+ /**
524
+ * What callers hand to a `tools` override. The canonical `ToolDeclaration`
525
+ * shape is accepted as-is; so is any framework shape `normalizeToolDeclarations`
526
+ * recognizes (OpenAI, Anthropic, Bedrock, LangChain, Pi, Mastra, AI SDK).
527
+ */
528
+ type ToolDeclarationInput = ToolDeclaration | {
529
+ name: string;
530
+ description?: string;
531
+ inputSchema?: JsonSchema;
532
+ parameters?: JsonSchema;
533
+ };
534
+ type PromptToolsOverride = ReadonlyArray<ToolDeclarationInput | unknown>;
509
535
 
510
536
  type SessionContext = {
511
537
  [Key in keyof Pick<Patch, "userId" | "convoId" | "eventName" | "properties">]?: Patch[Key] | undefined;
538
+ } & {
539
+ /**
540
+ * Overrides the tool catalog recorded as `ai.prompt.tools` on every model
541
+ * span. Use when the integration cannot see the tools the model was given.
542
+ * Without it the agent definition on the session (`session.agent.tools`) is used.
543
+ */
544
+ tools?: PromptToolsOverride | undefined;
512
545
  };
513
546
  type OpenAIManagedAgentsOptions = SessionContext & {
514
547
  writeKey?: string | undefined;
package/dist/index.d.ts CHANGED
@@ -506,9 +506,42 @@ declare global {
506
506
  var RAINDROP_CONTEXT_MANAGER: (new () => ContextManager) | undefined;
507
507
  var RAINDROP_ASYNC_LOCAL_STORAGE: (new <T>() => AsyncLocalStorageLike<T>) | undefined;
508
508
  }
509
+ type JsonSchema = Record<string, unknown>;
510
+ type FunctionToolDeclaration = {
511
+ type: "function";
512
+ name: string;
513
+ description?: string;
514
+ inputSchema?: JsonSchema;
515
+ };
516
+ type ProviderDefinedToolDeclaration = {
517
+ type: "provider-defined";
518
+ id?: string;
519
+ name: string;
520
+ args?: Record<string, unknown>;
521
+ };
522
+ type ToolDeclaration = FunctionToolDeclaration | ProviderDefinedToolDeclaration;
523
+ /**
524
+ * What callers hand to a `tools` override. The canonical `ToolDeclaration`
525
+ * shape is accepted as-is; so is any framework shape `normalizeToolDeclarations`
526
+ * recognizes (OpenAI, Anthropic, Bedrock, LangChain, Pi, Mastra, AI SDK).
527
+ */
528
+ type ToolDeclarationInput = ToolDeclaration | {
529
+ name: string;
530
+ description?: string;
531
+ inputSchema?: JsonSchema;
532
+ parameters?: JsonSchema;
533
+ };
534
+ type PromptToolsOverride = ReadonlyArray<ToolDeclarationInput | unknown>;
509
535
 
510
536
  type SessionContext = {
511
537
  [Key in keyof Pick<Patch, "userId" | "convoId" | "eventName" | "properties">]?: Patch[Key] | undefined;
538
+ } & {
539
+ /**
540
+ * Overrides the tool catalog recorded as `ai.prompt.tools` on every model
541
+ * span. Use when the integration cannot see the tools the model was given.
542
+ * Without it the agent definition on the session (`session.agent.tools`) is used.
543
+ */
544
+ tools?: PromptToolsOverride | undefined;
512
545
  };
513
546
  type OpenAIManagedAgentsOptions = SessionContext & {
514
547
  writeKey?: string | undefined;
package/dist/index.js CHANGED
@@ -87,7 +87,7 @@ function evalScopeAttributes() {
87
87
  return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
88
88
  }
89
89
 
90
- // ../core/dist/chunk-WJOR6M7H.js
90
+ // ../core/dist/chunk-I6TVJQEC.js
91
91
  var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
92
92
  function state() {
93
93
  const holder = globalThis;
@@ -2169,6 +2169,158 @@ var TraceShipper = class {
2169
2169
  }
2170
2170
  }
2171
2171
  };
2172
+ var PROMPT_TOOLS_ATTRIBUTE = "ai.prompt.tools";
2173
+ function isRecord(value) {
2174
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2175
+ }
2176
+ var JSON_SCHEMA_KEYS = [
2177
+ "type",
2178
+ "properties",
2179
+ "$schema",
2180
+ "$ref",
2181
+ "anyOf",
2182
+ "oneOf",
2183
+ "allOf",
2184
+ "enum",
2185
+ "const",
2186
+ "items",
2187
+ "additionalProperties",
2188
+ "required"
2189
+ ];
2190
+ function isJsonSchema(value) {
2191
+ if (!isRecord(value)) return false;
2192
+ if (typeof value["~standard"] === "object") return false;
2193
+ if (isRecord(value._def) || isRecord(value._zod)) return false;
2194
+ if (Object.keys(value).length === 0) return true;
2195
+ return JSON_SCHEMA_KEYS.some((key) => key in value);
2196
+ }
2197
+ function toJsonSchema(value, options) {
2198
+ if (value === void 0 || value === null) return void 0;
2199
+ if (isJsonSchema(value)) return value;
2200
+ if (isRecord(value) && isJsonSchema(value.jsonSchema)) return value.jsonSchema;
2201
+ if (isRecord(value) && isJsonSchema(value.json)) return value.json;
2202
+ if (options == null ? void 0 : options.schema) {
2203
+ try {
2204
+ return options.schema(value);
2205
+ } catch (e) {
2206
+ return void 0;
2207
+ }
2208
+ }
2209
+ return void 0;
2210
+ }
2211
+ function pickString(value) {
2212
+ return typeof value === "string" && value.length > 0 ? value : void 0;
2213
+ }
2214
+ function functionTool(name, description, schema, options) {
2215
+ const tool = { type: "function", name };
2216
+ const desc = pickString(description);
2217
+ if (desc !== void 0) tool.description = desc;
2218
+ const inputSchema = toJsonSchema(schema, options);
2219
+ if (inputSchema !== void 0) tool.inputSchema = inputSchema;
2220
+ return tool;
2221
+ }
2222
+ function normalizeToolDeclaration(tool, options, fallbackName) {
2223
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2224
+ if (!isRecord(tool)) return void 0;
2225
+ if (tool.type === "provider-defined" || tool.type === "provider") {
2226
+ const name2 = (_b = (_a = pickString(tool.name)) != null ? _a : pickString(tool.id)) != null ? _b : fallbackName;
2227
+ if (name2 === void 0) return void 0;
2228
+ const declaration = { type: "provider-defined", name: name2 };
2229
+ const id = pickString(tool.id);
2230
+ if (id !== void 0) declaration.id = id;
2231
+ if (isRecord(tool.args)) declaration.args = tool.args;
2232
+ return declaration;
2233
+ }
2234
+ if (isRecord(tool.toolSpec)) {
2235
+ const spec = tool.toolSpec;
2236
+ const name2 = (_c = pickString(spec.name)) != null ? _c : fallbackName;
2237
+ if (name2 === void 0) return void 0;
2238
+ return functionTool(name2, spec.description, spec.inputSchema, options);
2239
+ }
2240
+ if (isRecord(tool.function)) {
2241
+ const fn = tool.function;
2242
+ const name2 = (_d = pickString(fn.name)) != null ? _d : fallbackName;
2243
+ if (name2 === void 0) return void 0;
2244
+ return functionTool(name2, fn.description, (_e = fn.parameters) != null ? _e : fn.input_schema, options);
2245
+ }
2246
+ const name = (_g = (_f = pickString(tool.name)) != null ? _f : pickString(tool.id)) != null ? _g : fallbackName;
2247
+ if (name === void 0) return void 0;
2248
+ const type = pickString(tool.type);
2249
+ if (type !== void 0 && type !== "function" && type !== "dynamic" && type !== "custom") {
2250
+ if (!("input_schema" in tool) && !("inputSchema" in tool) && !("parameters" in tool)) {
2251
+ return { type: "provider-defined", id: type, name };
2252
+ }
2253
+ }
2254
+ return functionTool(
2255
+ name,
2256
+ tool.description,
2257
+ (_j = (_i = (_h = tool.inputSchema) != null ? _h : tool.input_schema) != null ? _i : tool.parameters) != null ? _j : tool.schema,
2258
+ options
2259
+ );
2260
+ }
2261
+ var NOT_A_GEMINI_GROUP_KEYS = ["name", "id", "type", "function", "toolSpec", "cachePoint"];
2262
+ function isGeminiToolGroup(tool) {
2263
+ if (Array.isArray(tool.functionDeclarations)) return true;
2264
+ const keys = Object.keys(tool);
2265
+ if (keys.length === 0 || NOT_A_GEMINI_GROUP_KEYS.some((key) => key in tool)) return false;
2266
+ return keys.every((key) => isRecord(tool[key]));
2267
+ }
2268
+ function expandGeminiTool(tool, options) {
2269
+ const declarations = [];
2270
+ for (const [key, value] of Object.entries(tool)) {
2271
+ if (key === "functionDeclarations" && Array.isArray(value)) {
2272
+ for (const declaration of value) {
2273
+ const normalized = normalizeToolDeclaration(declaration, options);
2274
+ if (normalized) declarations.push(normalized);
2275
+ }
2276
+ } else if (isRecord(value)) {
2277
+ declarations.push({ type: "provider-defined", id: key, name: key, args: value });
2278
+ }
2279
+ }
2280
+ return declarations;
2281
+ }
2282
+ function normalizeToolDeclarations(tools, options) {
2283
+ if (tools === void 0 || tools === null) return void 0;
2284
+ if (Array.isArray(tools)) {
2285
+ return tools.flatMap((tool) => {
2286
+ if (isRecord(tool) && isGeminiToolGroup(tool)) {
2287
+ return expandGeminiTool(tool, options);
2288
+ }
2289
+ const declaration = normalizeToolDeclaration(tool, options);
2290
+ return declaration ? [declaration] : [];
2291
+ });
2292
+ }
2293
+ if (!isRecord(tools)) return void 0;
2294
+ return Object.entries(tools).flatMap(([key, tool]) => {
2295
+ const declaration = normalizeToolDeclaration(tool, options, key);
2296
+ return declaration ? [declaration] : [];
2297
+ });
2298
+ }
2299
+ function resolvePromptTools(args) {
2300
+ var _a;
2301
+ if (args.override !== void 0) {
2302
+ return (_a = normalizeToolDeclarations(args.override, args.options)) != null ? _a : [];
2303
+ }
2304
+ return normalizeToolDeclarations(args.inferred, args.options);
2305
+ }
2306
+ function promptToolsAttribute(tools) {
2307
+ const values = promptToolsAttributeValue(tools);
2308
+ if (values === void 0) return void 0;
2309
+ return {
2310
+ key: PROMPT_TOOLS_ATTRIBUTE,
2311
+ value: { arrayValue: { values: values.map((stringValue) => ({ stringValue })) } }
2312
+ };
2313
+ }
2314
+ function promptToolsAttributeValue(tools) {
2315
+ if (tools === void 0) return void 0;
2316
+ return tools.map((tool) => {
2317
+ try {
2318
+ return JSON.stringify(tool);
2319
+ } catch (e) {
2320
+ return JSON.stringify({ type: tool.type, name: tool.name });
2321
+ }
2322
+ });
2323
+ }
2172
2324
 
2173
2325
  // ../core/dist/index.node.js
2174
2326
  var import_async_hooks = require("async_hooks");
@@ -2345,6 +2497,21 @@ function installTracingSuppressionHook() {
2345
2497
  installTracingSuppressionHook();
2346
2498
 
2347
2499
  // src/handler.ts
2500
+ var AGENT_CONFIG_SOURCE = {
2501
+ key: "ai.prompt.tools.source",
2502
+ value: { stringValue: "agent.config" }
2503
+ };
2504
+ function agentConfigTools(tools) {
2505
+ if (!Array.isArray(tools)) return void 0;
2506
+ return tools.map((tool) => {
2507
+ if (!isRecord2(tool)) return tool;
2508
+ const record = tool;
2509
+ if (typeof record.name === "string" || typeof record.type !== "string") return tool;
2510
+ const { type, ...args } = record;
2511
+ const name = typeof record.server_label === "string" ? record.server_label : type;
2512
+ return { type: "provider-defined", id: type, name, args };
2513
+ });
2514
+ }
2348
2515
  var RaindropManagedAgentsHandler = class {
2349
2516
  constructor(events, traces, opts) {
2350
2517
  this.events = events;
@@ -2398,6 +2565,12 @@ var RaindropManagedAgentsHandler = class {
2398
2565
  ...context.properties
2399
2566
  }
2400
2567
  };
2568
+ const override = capture.context.tools;
2569
+ const toolsAttr = promptToolsAttribute(
2570
+ resolvePromptTools({ override, inferred: agentConfigTools(session.agent.tools) })
2571
+ );
2572
+ capture.promptToolsOverridden = override !== void 0;
2573
+ capture.promptTools = !toolsAttr ? void 0 : override !== void 0 ? [toolsAttr] : [toolsAttr, AGENT_CONFIG_SOURCE];
2401
2574
  this.cacheSession(session.id, capture);
2402
2575
  } catch (e) {
2403
2576
  }
@@ -2479,8 +2652,8 @@ var RaindropManagedAgentsHandler = class {
2479
2652
  attrInt("openai.turn.started_at", (_a = turn.started_at) != null ? _a : void 0),
2480
2653
  attrInt("openai.turn.completed_at", (_b = turn.completed_at) != null ? _b : void 0)
2481
2654
  ]);
2655
+ const session = this.sessions.get(turn.session_id);
2482
2656
  if (turn.subagent_id === null) {
2483
- const session = this.sessions.get(turn.session_id);
2484
2657
  capture.patch.model = session == null ? void 0 : session.model;
2485
2658
  if (!capture.inputFromItem) capture.patch.input = session == null ? void 0 : session.input;
2486
2659
  this.setAttributes(capture.root, [
@@ -2489,6 +2662,9 @@ var RaindropManagedAgentsHandler = class {
2489
2662
  attrString("gen_ai.response.model", session == null ? void 0 : session.model)
2490
2663
  ]);
2491
2664
  }
2665
+ if ((session == null ? void 0 : session.promptTools) && (turn.subagent_id === null || session.promptToolsOverridden)) {
2666
+ this.setAttributes(capture.root, session.promptTools);
2667
+ }
2492
2668
  if (turn.subagent_id)
2493
2669
  capture.patch.properties = {
2494
2670
  ...capture.patch.properties,
@@ -2743,11 +2919,14 @@ var RaindropManagedAgentsHandler = class {
2743
2919
  this.completed.clear();
2744
2920
  }
2745
2921
  };
2922
+ function isRecord2(value) {
2923
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2924
+ }
2746
2925
 
2747
2926
  // package.json
2748
2927
  var package_default = {
2749
2928
  name: "@raindrop-ai/openai-managed-agents",
2750
- version: "0.0.2",
2929
+ version: "0.0.3",
2751
2930
  description: "Raindrop tracing for the OpenAI Agents API",
2752
2931
  main: "dist/index.js",
2753
2932
  module: "dist/index.mjs",
package/dist/index.mjs CHANGED
@@ -60,7 +60,7 @@ function evalScopeAttributes() {
60
60
  return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
61
61
  }
62
62
 
63
- // ../core/dist/chunk-WJOR6M7H.js
63
+ // ../core/dist/chunk-I6TVJQEC.js
64
64
  var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
65
65
  function state() {
66
66
  const holder = globalThis;
@@ -2142,6 +2142,158 @@ var TraceShipper = class {
2142
2142
  }
2143
2143
  }
2144
2144
  };
2145
+ var PROMPT_TOOLS_ATTRIBUTE = "ai.prompt.tools";
2146
+ function isRecord(value) {
2147
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2148
+ }
2149
+ var JSON_SCHEMA_KEYS = [
2150
+ "type",
2151
+ "properties",
2152
+ "$schema",
2153
+ "$ref",
2154
+ "anyOf",
2155
+ "oneOf",
2156
+ "allOf",
2157
+ "enum",
2158
+ "const",
2159
+ "items",
2160
+ "additionalProperties",
2161
+ "required"
2162
+ ];
2163
+ function isJsonSchema(value) {
2164
+ if (!isRecord(value)) return false;
2165
+ if (typeof value["~standard"] === "object") return false;
2166
+ if (isRecord(value._def) || isRecord(value._zod)) return false;
2167
+ if (Object.keys(value).length === 0) return true;
2168
+ return JSON_SCHEMA_KEYS.some((key) => key in value);
2169
+ }
2170
+ function toJsonSchema(value, options) {
2171
+ if (value === void 0 || value === null) return void 0;
2172
+ if (isJsonSchema(value)) return value;
2173
+ if (isRecord(value) && isJsonSchema(value.jsonSchema)) return value.jsonSchema;
2174
+ if (isRecord(value) && isJsonSchema(value.json)) return value.json;
2175
+ if (options == null ? void 0 : options.schema) {
2176
+ try {
2177
+ return options.schema(value);
2178
+ } catch (e) {
2179
+ return void 0;
2180
+ }
2181
+ }
2182
+ return void 0;
2183
+ }
2184
+ function pickString(value) {
2185
+ return typeof value === "string" && value.length > 0 ? value : void 0;
2186
+ }
2187
+ function functionTool(name, description, schema, options) {
2188
+ const tool = { type: "function", name };
2189
+ const desc = pickString(description);
2190
+ if (desc !== void 0) tool.description = desc;
2191
+ const inputSchema = toJsonSchema(schema, options);
2192
+ if (inputSchema !== void 0) tool.inputSchema = inputSchema;
2193
+ return tool;
2194
+ }
2195
+ function normalizeToolDeclaration(tool, options, fallbackName) {
2196
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2197
+ if (!isRecord(tool)) return void 0;
2198
+ if (tool.type === "provider-defined" || tool.type === "provider") {
2199
+ const name2 = (_b = (_a = pickString(tool.name)) != null ? _a : pickString(tool.id)) != null ? _b : fallbackName;
2200
+ if (name2 === void 0) return void 0;
2201
+ const declaration = { type: "provider-defined", name: name2 };
2202
+ const id = pickString(tool.id);
2203
+ if (id !== void 0) declaration.id = id;
2204
+ if (isRecord(tool.args)) declaration.args = tool.args;
2205
+ return declaration;
2206
+ }
2207
+ if (isRecord(tool.toolSpec)) {
2208
+ const spec = tool.toolSpec;
2209
+ const name2 = (_c = pickString(spec.name)) != null ? _c : fallbackName;
2210
+ if (name2 === void 0) return void 0;
2211
+ return functionTool(name2, spec.description, spec.inputSchema, options);
2212
+ }
2213
+ if (isRecord(tool.function)) {
2214
+ const fn = tool.function;
2215
+ const name2 = (_d = pickString(fn.name)) != null ? _d : fallbackName;
2216
+ if (name2 === void 0) return void 0;
2217
+ return functionTool(name2, fn.description, (_e = fn.parameters) != null ? _e : fn.input_schema, options);
2218
+ }
2219
+ const name = (_g = (_f = pickString(tool.name)) != null ? _f : pickString(tool.id)) != null ? _g : fallbackName;
2220
+ if (name === void 0) return void 0;
2221
+ const type = pickString(tool.type);
2222
+ if (type !== void 0 && type !== "function" && type !== "dynamic" && type !== "custom") {
2223
+ if (!("input_schema" in tool) && !("inputSchema" in tool) && !("parameters" in tool)) {
2224
+ return { type: "provider-defined", id: type, name };
2225
+ }
2226
+ }
2227
+ return functionTool(
2228
+ name,
2229
+ tool.description,
2230
+ (_j = (_i = (_h = tool.inputSchema) != null ? _h : tool.input_schema) != null ? _i : tool.parameters) != null ? _j : tool.schema,
2231
+ options
2232
+ );
2233
+ }
2234
+ var NOT_A_GEMINI_GROUP_KEYS = ["name", "id", "type", "function", "toolSpec", "cachePoint"];
2235
+ function isGeminiToolGroup(tool) {
2236
+ if (Array.isArray(tool.functionDeclarations)) return true;
2237
+ const keys = Object.keys(tool);
2238
+ if (keys.length === 0 || NOT_A_GEMINI_GROUP_KEYS.some((key) => key in tool)) return false;
2239
+ return keys.every((key) => isRecord(tool[key]));
2240
+ }
2241
+ function expandGeminiTool(tool, options) {
2242
+ const declarations = [];
2243
+ for (const [key, value] of Object.entries(tool)) {
2244
+ if (key === "functionDeclarations" && Array.isArray(value)) {
2245
+ for (const declaration of value) {
2246
+ const normalized = normalizeToolDeclaration(declaration, options);
2247
+ if (normalized) declarations.push(normalized);
2248
+ }
2249
+ } else if (isRecord(value)) {
2250
+ declarations.push({ type: "provider-defined", id: key, name: key, args: value });
2251
+ }
2252
+ }
2253
+ return declarations;
2254
+ }
2255
+ function normalizeToolDeclarations(tools, options) {
2256
+ if (tools === void 0 || tools === null) return void 0;
2257
+ if (Array.isArray(tools)) {
2258
+ return tools.flatMap((tool) => {
2259
+ if (isRecord(tool) && isGeminiToolGroup(tool)) {
2260
+ return expandGeminiTool(tool, options);
2261
+ }
2262
+ const declaration = normalizeToolDeclaration(tool, options);
2263
+ return declaration ? [declaration] : [];
2264
+ });
2265
+ }
2266
+ if (!isRecord(tools)) return void 0;
2267
+ return Object.entries(tools).flatMap(([key, tool]) => {
2268
+ const declaration = normalizeToolDeclaration(tool, options, key);
2269
+ return declaration ? [declaration] : [];
2270
+ });
2271
+ }
2272
+ function resolvePromptTools(args) {
2273
+ var _a;
2274
+ if (args.override !== void 0) {
2275
+ return (_a = normalizeToolDeclarations(args.override, args.options)) != null ? _a : [];
2276
+ }
2277
+ return normalizeToolDeclarations(args.inferred, args.options);
2278
+ }
2279
+ function promptToolsAttribute(tools) {
2280
+ const values = promptToolsAttributeValue(tools);
2281
+ if (values === void 0) return void 0;
2282
+ return {
2283
+ key: PROMPT_TOOLS_ATTRIBUTE,
2284
+ value: { arrayValue: { values: values.map((stringValue) => ({ stringValue })) } }
2285
+ };
2286
+ }
2287
+ function promptToolsAttributeValue(tools) {
2288
+ if (tools === void 0) return void 0;
2289
+ return tools.map((tool) => {
2290
+ try {
2291
+ return JSON.stringify(tool);
2292
+ } catch (e) {
2293
+ return JSON.stringify({ type: tool.type, name: tool.name });
2294
+ }
2295
+ });
2296
+ }
2145
2297
 
2146
2298
  // ../core/dist/index.node.js
2147
2299
  import { AsyncLocalStorage } from "async_hooks";
@@ -2318,6 +2470,21 @@ function installTracingSuppressionHook() {
2318
2470
  installTracingSuppressionHook();
2319
2471
 
2320
2472
  // src/handler.ts
2473
+ var AGENT_CONFIG_SOURCE = {
2474
+ key: "ai.prompt.tools.source",
2475
+ value: { stringValue: "agent.config" }
2476
+ };
2477
+ function agentConfigTools(tools) {
2478
+ if (!Array.isArray(tools)) return void 0;
2479
+ return tools.map((tool) => {
2480
+ if (!isRecord2(tool)) return tool;
2481
+ const record = tool;
2482
+ if (typeof record.name === "string" || typeof record.type !== "string") return tool;
2483
+ const { type, ...args } = record;
2484
+ const name = typeof record.server_label === "string" ? record.server_label : type;
2485
+ return { type: "provider-defined", id: type, name, args };
2486
+ });
2487
+ }
2321
2488
  var RaindropManagedAgentsHandler = class {
2322
2489
  constructor(events, traces, opts) {
2323
2490
  this.events = events;
@@ -2371,6 +2538,12 @@ var RaindropManagedAgentsHandler = class {
2371
2538
  ...context.properties
2372
2539
  }
2373
2540
  };
2541
+ const override = capture.context.tools;
2542
+ const toolsAttr = promptToolsAttribute(
2543
+ resolvePromptTools({ override, inferred: agentConfigTools(session.agent.tools) })
2544
+ );
2545
+ capture.promptToolsOverridden = override !== void 0;
2546
+ capture.promptTools = !toolsAttr ? void 0 : override !== void 0 ? [toolsAttr] : [toolsAttr, AGENT_CONFIG_SOURCE];
2374
2547
  this.cacheSession(session.id, capture);
2375
2548
  } catch (e) {
2376
2549
  }
@@ -2452,8 +2625,8 @@ var RaindropManagedAgentsHandler = class {
2452
2625
  attrInt("openai.turn.started_at", (_a = turn.started_at) != null ? _a : void 0),
2453
2626
  attrInt("openai.turn.completed_at", (_b = turn.completed_at) != null ? _b : void 0)
2454
2627
  ]);
2628
+ const session = this.sessions.get(turn.session_id);
2455
2629
  if (turn.subagent_id === null) {
2456
- const session = this.sessions.get(turn.session_id);
2457
2630
  capture.patch.model = session == null ? void 0 : session.model;
2458
2631
  if (!capture.inputFromItem) capture.patch.input = session == null ? void 0 : session.input;
2459
2632
  this.setAttributes(capture.root, [
@@ -2462,6 +2635,9 @@ var RaindropManagedAgentsHandler = class {
2462
2635
  attrString("gen_ai.response.model", session == null ? void 0 : session.model)
2463
2636
  ]);
2464
2637
  }
2638
+ if ((session == null ? void 0 : session.promptTools) && (turn.subagent_id === null || session.promptToolsOverridden)) {
2639
+ this.setAttributes(capture.root, session.promptTools);
2640
+ }
2465
2641
  if (turn.subagent_id)
2466
2642
  capture.patch.properties = {
2467
2643
  ...capture.patch.properties,
@@ -2716,11 +2892,14 @@ var RaindropManagedAgentsHandler = class {
2716
2892
  this.completed.clear();
2717
2893
  }
2718
2894
  };
2895
+ function isRecord2(value) {
2896
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2897
+ }
2719
2898
 
2720
2899
  // package.json
2721
2900
  var package_default = {
2722
2901
  name: "@raindrop-ai/openai-managed-agents",
2723
- version: "0.0.2",
2902
+ version: "0.0.3",
2724
2903
  description: "Raindrop tracing for the OpenAI Agents API",
2725
2904
  main: "dist/index.js",
2726
2905
  module: "dist/index.mjs",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raindrop-ai/openai-managed-agents",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Raindrop tracing for the OpenAI Agents API",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -38,7 +38,7 @@
38
38
  "vitest": "^2.1.9",
39
39
  "openai": "7.15.0",
40
40
  "zod": "^3.23.8",
41
- "@raindrop-ai/core": "0.3.0"
41
+ "@raindrop-ai/core": "0.3.1"
42
42
  },
43
43
  "tsup": {
44
44
  "entry": [