@raindrop-ai/claude-code 0.0.20 → 0.0.21
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/.claude-plugin/plugin.json +1 -1
- package/README.md +22 -0
- package/dist/cli.js +178 -8
- package/dist/index.cjs +176 -7
- package/dist/index.d.cts +33 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +176 -7
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -45,6 +45,28 @@ Tag events with product names or custom metadata via `.claude/settings.json`:
|
|
|
45
45
|
}
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
## Tool catalog capture (`ai.prompt.tools`)
|
|
49
|
+
|
|
50
|
+
Claude Code hooks and transcripts never expose the request Claude Code sends to the model, so this
|
|
51
|
+
integration cannot observe the tool catalog and records nothing by default (the attribute stays
|
|
52
|
+
absent, meaning "unknown"). Supply the catalog yourself with `tools` — an array of tool
|
|
53
|
+
declarations in any shape `@raindrop-ai/core` recognizes (`{ name, description?, parameters }`,
|
|
54
|
+
`{ type: "function", name, inputSchema }`, OpenAI/Anthropic wrappers, ...):
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"tools": [
|
|
59
|
+
{ "name": "read_file", "description": "Read a file", "parameters": { "type": "object", "properties": { "path": { "type": "string" } }, "required": ["path"] } }
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Set it in `~/.config/raindrop/config.json` (`tools`) or as JSON in the `RAINDROP_TOOLS` environment
|
|
65
|
+
variable (the variable wins). The override is recorded verbatim as `ai.prompt.tools` on every LLM
|
|
66
|
+
span reconstructed from the transcript (`gen_ai.response.model` spans), never on tool-call,
|
|
67
|
+
subagent, or permission spans, and `tools: []` records an explicitly empty catalog. Nothing is
|
|
68
|
+
inferred from hook payloads: implicit capture is not possible here.
|
|
69
|
+
|
|
48
70
|
## Custom Self-Diagnostics Signals
|
|
49
71
|
|
|
50
72
|
Replace the built-in signal categories with your own via `~/.config/raindrop/config.json`:
|
package/dist/cli.js
CHANGED
|
@@ -69,7 +69,7 @@ function evalScopeAttributes() {
|
|
|
69
69
|
return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
// ../core/dist/chunk-
|
|
72
|
+
// ../core/dist/chunk-I6TVJQEC.js
|
|
73
73
|
var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
|
|
74
74
|
function state() {
|
|
75
75
|
const holder = globalThis;
|
|
@@ -2056,6 +2056,158 @@ var TraceShipper = class {
|
|
|
2056
2056
|
}
|
|
2057
2057
|
}
|
|
2058
2058
|
};
|
|
2059
|
+
var PROMPT_TOOLS_ATTRIBUTE = "ai.prompt.tools";
|
|
2060
|
+
function isRecord(value) {
|
|
2061
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2062
|
+
}
|
|
2063
|
+
var JSON_SCHEMA_KEYS = [
|
|
2064
|
+
"type",
|
|
2065
|
+
"properties",
|
|
2066
|
+
"$schema",
|
|
2067
|
+
"$ref",
|
|
2068
|
+
"anyOf",
|
|
2069
|
+
"oneOf",
|
|
2070
|
+
"allOf",
|
|
2071
|
+
"enum",
|
|
2072
|
+
"const",
|
|
2073
|
+
"items",
|
|
2074
|
+
"additionalProperties",
|
|
2075
|
+
"required"
|
|
2076
|
+
];
|
|
2077
|
+
function isJsonSchema(value) {
|
|
2078
|
+
if (!isRecord(value)) return false;
|
|
2079
|
+
if (typeof value["~standard"] === "object") return false;
|
|
2080
|
+
if (isRecord(value._def) || isRecord(value._zod)) return false;
|
|
2081
|
+
if (Object.keys(value).length === 0) return true;
|
|
2082
|
+
return JSON_SCHEMA_KEYS.some((key) => key in value);
|
|
2083
|
+
}
|
|
2084
|
+
function toJsonSchema(value, options) {
|
|
2085
|
+
if (value === void 0 || value === null) return void 0;
|
|
2086
|
+
if (isJsonSchema(value)) return value;
|
|
2087
|
+
if (isRecord(value) && isJsonSchema(value.jsonSchema)) return value.jsonSchema;
|
|
2088
|
+
if (isRecord(value) && isJsonSchema(value.json)) return value.json;
|
|
2089
|
+
if (options == null ? void 0 : options.schema) {
|
|
2090
|
+
try {
|
|
2091
|
+
return options.schema(value);
|
|
2092
|
+
} catch (e) {
|
|
2093
|
+
return void 0;
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
return void 0;
|
|
2097
|
+
}
|
|
2098
|
+
function pickString(value) {
|
|
2099
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
2100
|
+
}
|
|
2101
|
+
function functionTool(name, description, schema, options) {
|
|
2102
|
+
const tool = { type: "function", name };
|
|
2103
|
+
const desc = pickString(description);
|
|
2104
|
+
if (desc !== void 0) tool.description = desc;
|
|
2105
|
+
const inputSchema = toJsonSchema(schema, options);
|
|
2106
|
+
if (inputSchema !== void 0) tool.inputSchema = inputSchema;
|
|
2107
|
+
return tool;
|
|
2108
|
+
}
|
|
2109
|
+
function normalizeToolDeclaration(tool, options, fallbackName) {
|
|
2110
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
2111
|
+
if (!isRecord(tool)) return void 0;
|
|
2112
|
+
if (tool.type === "provider-defined" || tool.type === "provider") {
|
|
2113
|
+
const name2 = (_b = (_a = pickString(tool.name)) != null ? _a : pickString(tool.id)) != null ? _b : fallbackName;
|
|
2114
|
+
if (name2 === void 0) return void 0;
|
|
2115
|
+
const declaration = { type: "provider-defined", name: name2 };
|
|
2116
|
+
const id = pickString(tool.id);
|
|
2117
|
+
if (id !== void 0) declaration.id = id;
|
|
2118
|
+
if (isRecord(tool.args)) declaration.args = tool.args;
|
|
2119
|
+
return declaration;
|
|
2120
|
+
}
|
|
2121
|
+
if (isRecord(tool.toolSpec)) {
|
|
2122
|
+
const spec = tool.toolSpec;
|
|
2123
|
+
const name2 = (_c = pickString(spec.name)) != null ? _c : fallbackName;
|
|
2124
|
+
if (name2 === void 0) return void 0;
|
|
2125
|
+
return functionTool(name2, spec.description, spec.inputSchema, options);
|
|
2126
|
+
}
|
|
2127
|
+
if (isRecord(tool.function)) {
|
|
2128
|
+
const fn = tool.function;
|
|
2129
|
+
const name2 = (_d = pickString(fn.name)) != null ? _d : fallbackName;
|
|
2130
|
+
if (name2 === void 0) return void 0;
|
|
2131
|
+
return functionTool(name2, fn.description, (_e = fn.parameters) != null ? _e : fn.input_schema, options);
|
|
2132
|
+
}
|
|
2133
|
+
const name = (_g = (_f = pickString(tool.name)) != null ? _f : pickString(tool.id)) != null ? _g : fallbackName;
|
|
2134
|
+
if (name === void 0) return void 0;
|
|
2135
|
+
const type = pickString(tool.type);
|
|
2136
|
+
if (type !== void 0 && type !== "function" && type !== "dynamic" && type !== "custom") {
|
|
2137
|
+
if (!("input_schema" in tool) && !("inputSchema" in tool) && !("parameters" in tool)) {
|
|
2138
|
+
return { type: "provider-defined", id: type, name };
|
|
2139
|
+
}
|
|
2140
|
+
}
|
|
2141
|
+
return functionTool(
|
|
2142
|
+
name,
|
|
2143
|
+
tool.description,
|
|
2144
|
+
(_j = (_i = (_h = tool.inputSchema) != null ? _h : tool.input_schema) != null ? _i : tool.parameters) != null ? _j : tool.schema,
|
|
2145
|
+
options
|
|
2146
|
+
);
|
|
2147
|
+
}
|
|
2148
|
+
var NOT_A_GEMINI_GROUP_KEYS = ["name", "id", "type", "function", "toolSpec", "cachePoint"];
|
|
2149
|
+
function isGeminiToolGroup(tool) {
|
|
2150
|
+
if (Array.isArray(tool.functionDeclarations)) return true;
|
|
2151
|
+
const keys = Object.keys(tool);
|
|
2152
|
+
if (keys.length === 0 || NOT_A_GEMINI_GROUP_KEYS.some((key) => key in tool)) return false;
|
|
2153
|
+
return keys.every((key) => isRecord(tool[key]));
|
|
2154
|
+
}
|
|
2155
|
+
function expandGeminiTool(tool, options) {
|
|
2156
|
+
const declarations = [];
|
|
2157
|
+
for (const [key, value] of Object.entries(tool)) {
|
|
2158
|
+
if (key === "functionDeclarations" && Array.isArray(value)) {
|
|
2159
|
+
for (const declaration of value) {
|
|
2160
|
+
const normalized = normalizeToolDeclaration(declaration, options);
|
|
2161
|
+
if (normalized) declarations.push(normalized);
|
|
2162
|
+
}
|
|
2163
|
+
} else if (isRecord(value)) {
|
|
2164
|
+
declarations.push({ type: "provider-defined", id: key, name: key, args: value });
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
return declarations;
|
|
2168
|
+
}
|
|
2169
|
+
function normalizeToolDeclarations(tools, options) {
|
|
2170
|
+
if (tools === void 0 || tools === null) return void 0;
|
|
2171
|
+
if (Array.isArray(tools)) {
|
|
2172
|
+
return tools.flatMap((tool) => {
|
|
2173
|
+
if (isRecord(tool) && isGeminiToolGroup(tool)) {
|
|
2174
|
+
return expandGeminiTool(tool, options);
|
|
2175
|
+
}
|
|
2176
|
+
const declaration = normalizeToolDeclaration(tool, options);
|
|
2177
|
+
return declaration ? [declaration] : [];
|
|
2178
|
+
});
|
|
2179
|
+
}
|
|
2180
|
+
if (!isRecord(tools)) return void 0;
|
|
2181
|
+
return Object.entries(tools).flatMap(([key, tool]) => {
|
|
2182
|
+
const declaration = normalizeToolDeclaration(tool, options, key);
|
|
2183
|
+
return declaration ? [declaration] : [];
|
|
2184
|
+
});
|
|
2185
|
+
}
|
|
2186
|
+
function resolvePromptTools(args2) {
|
|
2187
|
+
var _a;
|
|
2188
|
+
if (args2.override !== void 0) {
|
|
2189
|
+
return (_a = normalizeToolDeclarations(args2.override, args2.options)) != null ? _a : [];
|
|
2190
|
+
}
|
|
2191
|
+
return normalizeToolDeclarations(args2.inferred, args2.options);
|
|
2192
|
+
}
|
|
2193
|
+
function promptToolsAttribute(tools) {
|
|
2194
|
+
const values = promptToolsAttributeValue(tools);
|
|
2195
|
+
if (values === void 0) return void 0;
|
|
2196
|
+
return {
|
|
2197
|
+
key: PROMPT_TOOLS_ATTRIBUTE,
|
|
2198
|
+
value: { arrayValue: { values: values.map((stringValue) => ({ stringValue })) } }
|
|
2199
|
+
};
|
|
2200
|
+
}
|
|
2201
|
+
function promptToolsAttributeValue(tools) {
|
|
2202
|
+
if (tools === void 0) return void 0;
|
|
2203
|
+
return tools.map((tool) => {
|
|
2204
|
+
try {
|
|
2205
|
+
return JSON.stringify(tool);
|
|
2206
|
+
} catch (e) {
|
|
2207
|
+
return JSON.stringify({ type: tool.type, name: tool.name });
|
|
2208
|
+
}
|
|
2209
|
+
});
|
|
2210
|
+
}
|
|
2059
2211
|
|
|
2060
2212
|
// ../core/dist/index.node.js
|
|
2061
2213
|
import { AsyncLocalStorage } from "async_hooks";
|
|
@@ -2234,7 +2386,7 @@ installTracingSuppressionHook();
|
|
|
2234
2386
|
// package.json
|
|
2235
2387
|
var package_default = {
|
|
2236
2388
|
name: "@raindrop-ai/claude-code",
|
|
2237
|
-
version: "0.0.
|
|
2389
|
+
version: "0.0.21",
|
|
2238
2390
|
description: "Raindrop observability for Claude Code CLI \u2014 automatic session, tool call, and prompt tracing via hooks",
|
|
2239
2391
|
license: "MIT",
|
|
2240
2392
|
homepage: "https://www.raindrop.ai/docs/integrations/claude-code/",
|
|
@@ -3143,7 +3295,7 @@ function isoToNanoString(iso, fallback) {
|
|
|
3143
3295
|
return fallback;
|
|
3144
3296
|
}
|
|
3145
3297
|
}
|
|
3146
|
-
function enrichFromTranscript(payload, eventId, traceShipper) {
|
|
3298
|
+
function enrichFromTranscript(payload, eventId, traceShipper, promptTools) {
|
|
3147
3299
|
var _a, _b, _c, _d;
|
|
3148
3300
|
if (!payload.transcript_path) {
|
|
3149
3301
|
return { summary: void 0, props: {} };
|
|
@@ -3182,7 +3334,8 @@ function enrichFromTranscript(payload, eventId, traceShipper) {
|
|
|
3182
3334
|
attrString("ai.response.text", truncate(outputText)),
|
|
3183
3335
|
...toolCallNames ? [attrString("ai.toolCall.names", toolCallNames)] : [],
|
|
3184
3336
|
...phase.hasThinking ? [attrString("ai.has_thinking", "true")] : [],
|
|
3185
|
-
attrInt("ai.llm_call.index", emittedPhaseIndex)
|
|
3337
|
+
attrInt("ai.llm_call.index", emittedPhaseIndex),
|
|
3338
|
+
promptTools
|
|
3186
3339
|
]
|
|
3187
3340
|
});
|
|
3188
3341
|
emittedPhaseIndex++;
|
|
@@ -3204,7 +3357,8 @@ function enrichFromTranscript(payload, eventId, traceShipper) {
|
|
|
3204
3357
|
attrString("gen_ai.system", "anthropic"),
|
|
3205
3358
|
attrInt("gen_ai.usage.prompt_tokens", spanInputTokens),
|
|
3206
3359
|
attrInt("gen_ai.usage.completion_tokens", spanOutputTokens),
|
|
3207
|
-
...summary.lastTurnCacheReadTokens != null && summary.lastTurnCacheReadTokens > 0 ? [attrInt("gen_ai.usage.cache_read_tokens", summary.lastTurnCacheReadTokens)] : []
|
|
3360
|
+
...summary.lastTurnCacheReadTokens != null && summary.lastTurnCacheReadTokens > 0 ? [attrInt("gen_ai.usage.cache_read_tokens", summary.lastTurnCacheReadTokens)] : [],
|
|
3361
|
+
promptTools
|
|
3208
3362
|
]
|
|
3209
3363
|
});
|
|
3210
3364
|
}
|
|
@@ -3230,7 +3384,12 @@ function buildStopOutput(summary, lastAssistantMessage) {
|
|
|
3230
3384
|
return finalMessage;
|
|
3231
3385
|
}
|
|
3232
3386
|
async function handleStopOrFailure(payload, eventId, convoId, config, properties, eventShipper, traceShipper, extraProperties) {
|
|
3233
|
-
const { summary, props: transcriptProps } = enrichFromTranscript(
|
|
3387
|
+
const { summary, props: transcriptProps } = enrichFromTranscript(
|
|
3388
|
+
payload,
|
|
3389
|
+
eventId,
|
|
3390
|
+
traceShipper,
|
|
3391
|
+
promptToolsAttribute(resolvePromptTools({ override: config.tools }))
|
|
3392
|
+
);
|
|
3234
3393
|
const instructions = gatherInstructions(payload.session_id);
|
|
3235
3394
|
const appendSysPrompt = readAppendSystemPrompt(payload.session_id);
|
|
3236
3395
|
const output = buildStopOutput(summary, payload.last_assistant_message);
|
|
@@ -3295,6 +3454,15 @@ function loadConfig() {
|
|
|
3295
3454
|
} catch (e) {
|
|
3296
3455
|
}
|
|
3297
3456
|
}
|
|
3457
|
+
let tools = Array.isArray(file.tools) ? file.tools : void 0;
|
|
3458
|
+
const envTools = process.env["RAINDROP_TOOLS"];
|
|
3459
|
+
if (envTools) {
|
|
3460
|
+
try {
|
|
3461
|
+
const parsed = JSON.parse(envTools);
|
|
3462
|
+
if (Array.isArray(parsed)) tools = parsed;
|
|
3463
|
+
} catch (e) {
|
|
3464
|
+
}
|
|
3465
|
+
}
|
|
3298
3466
|
let selfDiagnostics = file.self_diagnostics;
|
|
3299
3467
|
const envDiag = process.env["RAINDROP_SELF_DIAGNOSTICS"];
|
|
3300
3468
|
if (envDiag) {
|
|
@@ -3323,7 +3491,8 @@ function loadConfig() {
|
|
|
3323
3491
|
eventName: (_l = (_k = process.env["RAINDROP_EVENT_NAME"]) != null ? _k : file.event_name) != null ? _l : "claude_code_session",
|
|
3324
3492
|
customProperties,
|
|
3325
3493
|
selfDiagnostics,
|
|
3326
|
-
appGit: mapAppGit(file.app_git)
|
|
3494
|
+
appGit: mapAppGit(file.app_git),
|
|
3495
|
+
tools
|
|
3327
3496
|
};
|
|
3328
3497
|
}
|
|
3329
3498
|
function mapAppGit(value) {
|
|
@@ -3545,7 +3714,8 @@ async function handleHook() {
|
|
|
3545
3714
|
convoId: config.convoId,
|
|
3546
3715
|
debug: config.debug,
|
|
3547
3716
|
eventName: config.eventName,
|
|
3548
|
-
customProperties: config.customProperties
|
|
3717
|
+
customProperties: config.customProperties,
|
|
3718
|
+
tools: config.tools
|
|
3549
3719
|
};
|
|
3550
3720
|
const appGitContext = createAppGitContext2(
|
|
3551
3721
|
((_a = config.writeKey) == null ? void 0 : _a.trim()) || hasDebugger ? config.appGit : false,
|
package/dist/index.cjs
CHANGED
|
@@ -106,7 +106,7 @@ function evalScopeAttributes() {
|
|
|
106
106
|
return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
// ../core/dist/chunk-
|
|
109
|
+
// ../core/dist/chunk-I6TVJQEC.js
|
|
110
110
|
var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
|
|
111
111
|
function state() {
|
|
112
112
|
const holder = globalThis;
|
|
@@ -2093,6 +2093,158 @@ var TraceShipper = class {
|
|
|
2093
2093
|
}
|
|
2094
2094
|
}
|
|
2095
2095
|
};
|
|
2096
|
+
var PROMPT_TOOLS_ATTRIBUTE = "ai.prompt.tools";
|
|
2097
|
+
function isRecord(value) {
|
|
2098
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2099
|
+
}
|
|
2100
|
+
var JSON_SCHEMA_KEYS = [
|
|
2101
|
+
"type",
|
|
2102
|
+
"properties",
|
|
2103
|
+
"$schema",
|
|
2104
|
+
"$ref",
|
|
2105
|
+
"anyOf",
|
|
2106
|
+
"oneOf",
|
|
2107
|
+
"allOf",
|
|
2108
|
+
"enum",
|
|
2109
|
+
"const",
|
|
2110
|
+
"items",
|
|
2111
|
+
"additionalProperties",
|
|
2112
|
+
"required"
|
|
2113
|
+
];
|
|
2114
|
+
function isJsonSchema(value) {
|
|
2115
|
+
if (!isRecord(value)) return false;
|
|
2116
|
+
if (typeof value["~standard"] === "object") return false;
|
|
2117
|
+
if (isRecord(value._def) || isRecord(value._zod)) return false;
|
|
2118
|
+
if (Object.keys(value).length === 0) return true;
|
|
2119
|
+
return JSON_SCHEMA_KEYS.some((key) => key in value);
|
|
2120
|
+
}
|
|
2121
|
+
function toJsonSchema(value, options) {
|
|
2122
|
+
if (value === void 0 || value === null) return void 0;
|
|
2123
|
+
if (isJsonSchema(value)) return value;
|
|
2124
|
+
if (isRecord(value) && isJsonSchema(value.jsonSchema)) return value.jsonSchema;
|
|
2125
|
+
if (isRecord(value) && isJsonSchema(value.json)) return value.json;
|
|
2126
|
+
if (options == null ? void 0 : options.schema) {
|
|
2127
|
+
try {
|
|
2128
|
+
return options.schema(value);
|
|
2129
|
+
} catch (e) {
|
|
2130
|
+
return void 0;
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
return void 0;
|
|
2134
|
+
}
|
|
2135
|
+
function pickString(value) {
|
|
2136
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
2137
|
+
}
|
|
2138
|
+
function functionTool(name, description, schema, options) {
|
|
2139
|
+
const tool = { type: "function", name };
|
|
2140
|
+
const desc = pickString(description);
|
|
2141
|
+
if (desc !== void 0) tool.description = desc;
|
|
2142
|
+
const inputSchema = toJsonSchema(schema, options);
|
|
2143
|
+
if (inputSchema !== void 0) tool.inputSchema = inputSchema;
|
|
2144
|
+
return tool;
|
|
2145
|
+
}
|
|
2146
|
+
function normalizeToolDeclaration(tool, options, fallbackName) {
|
|
2147
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
2148
|
+
if (!isRecord(tool)) return void 0;
|
|
2149
|
+
if (tool.type === "provider-defined" || tool.type === "provider") {
|
|
2150
|
+
const name2 = (_b = (_a = pickString(tool.name)) != null ? _a : pickString(tool.id)) != null ? _b : fallbackName;
|
|
2151
|
+
if (name2 === void 0) return void 0;
|
|
2152
|
+
const declaration = { type: "provider-defined", name: name2 };
|
|
2153
|
+
const id = pickString(tool.id);
|
|
2154
|
+
if (id !== void 0) declaration.id = id;
|
|
2155
|
+
if (isRecord(tool.args)) declaration.args = tool.args;
|
|
2156
|
+
return declaration;
|
|
2157
|
+
}
|
|
2158
|
+
if (isRecord(tool.toolSpec)) {
|
|
2159
|
+
const spec = tool.toolSpec;
|
|
2160
|
+
const name2 = (_c = pickString(spec.name)) != null ? _c : fallbackName;
|
|
2161
|
+
if (name2 === void 0) return void 0;
|
|
2162
|
+
return functionTool(name2, spec.description, spec.inputSchema, options);
|
|
2163
|
+
}
|
|
2164
|
+
if (isRecord(tool.function)) {
|
|
2165
|
+
const fn = tool.function;
|
|
2166
|
+
const name2 = (_d = pickString(fn.name)) != null ? _d : fallbackName;
|
|
2167
|
+
if (name2 === void 0) return void 0;
|
|
2168
|
+
return functionTool(name2, fn.description, (_e = fn.parameters) != null ? _e : fn.input_schema, options);
|
|
2169
|
+
}
|
|
2170
|
+
const name = (_g = (_f = pickString(tool.name)) != null ? _f : pickString(tool.id)) != null ? _g : fallbackName;
|
|
2171
|
+
if (name === void 0) return void 0;
|
|
2172
|
+
const type = pickString(tool.type);
|
|
2173
|
+
if (type !== void 0 && type !== "function" && type !== "dynamic" && type !== "custom") {
|
|
2174
|
+
if (!("input_schema" in tool) && !("inputSchema" in tool) && !("parameters" in tool)) {
|
|
2175
|
+
return { type: "provider-defined", id: type, name };
|
|
2176
|
+
}
|
|
2177
|
+
}
|
|
2178
|
+
return functionTool(
|
|
2179
|
+
name,
|
|
2180
|
+
tool.description,
|
|
2181
|
+
(_j = (_i = (_h = tool.inputSchema) != null ? _h : tool.input_schema) != null ? _i : tool.parameters) != null ? _j : tool.schema,
|
|
2182
|
+
options
|
|
2183
|
+
);
|
|
2184
|
+
}
|
|
2185
|
+
var NOT_A_GEMINI_GROUP_KEYS = ["name", "id", "type", "function", "toolSpec", "cachePoint"];
|
|
2186
|
+
function isGeminiToolGroup(tool) {
|
|
2187
|
+
if (Array.isArray(tool.functionDeclarations)) return true;
|
|
2188
|
+
const keys = Object.keys(tool);
|
|
2189
|
+
if (keys.length === 0 || NOT_A_GEMINI_GROUP_KEYS.some((key) => key in tool)) return false;
|
|
2190
|
+
return keys.every((key) => isRecord(tool[key]));
|
|
2191
|
+
}
|
|
2192
|
+
function expandGeminiTool(tool, options) {
|
|
2193
|
+
const declarations = [];
|
|
2194
|
+
for (const [key, value] of Object.entries(tool)) {
|
|
2195
|
+
if (key === "functionDeclarations" && Array.isArray(value)) {
|
|
2196
|
+
for (const declaration of value) {
|
|
2197
|
+
const normalized = normalizeToolDeclaration(declaration, options);
|
|
2198
|
+
if (normalized) declarations.push(normalized);
|
|
2199
|
+
}
|
|
2200
|
+
} else if (isRecord(value)) {
|
|
2201
|
+
declarations.push({ type: "provider-defined", id: key, name: key, args: value });
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
return declarations;
|
|
2205
|
+
}
|
|
2206
|
+
function normalizeToolDeclarations(tools, options) {
|
|
2207
|
+
if (tools === void 0 || tools === null) return void 0;
|
|
2208
|
+
if (Array.isArray(tools)) {
|
|
2209
|
+
return tools.flatMap((tool) => {
|
|
2210
|
+
if (isRecord(tool) && isGeminiToolGroup(tool)) {
|
|
2211
|
+
return expandGeminiTool(tool, options);
|
|
2212
|
+
}
|
|
2213
|
+
const declaration = normalizeToolDeclaration(tool, options);
|
|
2214
|
+
return declaration ? [declaration] : [];
|
|
2215
|
+
});
|
|
2216
|
+
}
|
|
2217
|
+
if (!isRecord(tools)) return void 0;
|
|
2218
|
+
return Object.entries(tools).flatMap(([key, tool]) => {
|
|
2219
|
+
const declaration = normalizeToolDeclaration(tool, options, key);
|
|
2220
|
+
return declaration ? [declaration] : [];
|
|
2221
|
+
});
|
|
2222
|
+
}
|
|
2223
|
+
function resolvePromptTools(args) {
|
|
2224
|
+
var _a;
|
|
2225
|
+
if (args.override !== void 0) {
|
|
2226
|
+
return (_a = normalizeToolDeclarations(args.override, args.options)) != null ? _a : [];
|
|
2227
|
+
}
|
|
2228
|
+
return normalizeToolDeclarations(args.inferred, args.options);
|
|
2229
|
+
}
|
|
2230
|
+
function promptToolsAttribute(tools) {
|
|
2231
|
+
const values = promptToolsAttributeValue(tools);
|
|
2232
|
+
if (values === void 0) return void 0;
|
|
2233
|
+
return {
|
|
2234
|
+
key: PROMPT_TOOLS_ATTRIBUTE,
|
|
2235
|
+
value: { arrayValue: { values: values.map((stringValue) => ({ stringValue })) } }
|
|
2236
|
+
};
|
|
2237
|
+
}
|
|
2238
|
+
function promptToolsAttributeValue(tools) {
|
|
2239
|
+
if (tools === void 0) return void 0;
|
|
2240
|
+
return tools.map((tool) => {
|
|
2241
|
+
try {
|
|
2242
|
+
return JSON.stringify(tool);
|
|
2243
|
+
} catch (e) {
|
|
2244
|
+
return JSON.stringify({ type: tool.type, name: tool.name });
|
|
2245
|
+
}
|
|
2246
|
+
});
|
|
2247
|
+
}
|
|
2096
2248
|
|
|
2097
2249
|
// ../core/dist/index.node.js
|
|
2098
2250
|
var import_async_hooks = require("async_hooks");
|
|
@@ -2271,7 +2423,7 @@ installTracingSuppressionHook();
|
|
|
2271
2423
|
// package.json
|
|
2272
2424
|
var package_default = {
|
|
2273
2425
|
name: "@raindrop-ai/claude-code",
|
|
2274
|
-
version: "0.0.
|
|
2426
|
+
version: "0.0.21",
|
|
2275
2427
|
description: "Raindrop observability for Claude Code CLI \u2014 automatic session, tool call, and prompt tracing via hooks",
|
|
2276
2428
|
license: "MIT",
|
|
2277
2429
|
homepage: "https://www.raindrop.ai/docs/integrations/claude-code/",
|
|
@@ -2411,6 +2563,15 @@ function loadConfig() {
|
|
|
2411
2563
|
} catch (e) {
|
|
2412
2564
|
}
|
|
2413
2565
|
}
|
|
2566
|
+
let tools = Array.isArray(file.tools) ? file.tools : void 0;
|
|
2567
|
+
const envTools = process.env["RAINDROP_TOOLS"];
|
|
2568
|
+
if (envTools) {
|
|
2569
|
+
try {
|
|
2570
|
+
const parsed = JSON.parse(envTools);
|
|
2571
|
+
if (Array.isArray(parsed)) tools = parsed;
|
|
2572
|
+
} catch (e) {
|
|
2573
|
+
}
|
|
2574
|
+
}
|
|
2414
2575
|
let selfDiagnostics = file.self_diagnostics;
|
|
2415
2576
|
const envDiag = process.env["RAINDROP_SELF_DIAGNOSTICS"];
|
|
2416
2577
|
if (envDiag) {
|
|
@@ -2439,7 +2600,8 @@ function loadConfig() {
|
|
|
2439
2600
|
eventName: (_l = (_k = process.env["RAINDROP_EVENT_NAME"]) != null ? _k : file.event_name) != null ? _l : "claude_code_session",
|
|
2440
2601
|
customProperties,
|
|
2441
2602
|
selfDiagnostics,
|
|
2442
|
-
appGit: mapAppGit(file.app_git)
|
|
2603
|
+
appGit: mapAppGit(file.app_git),
|
|
2604
|
+
tools
|
|
2443
2605
|
};
|
|
2444
2606
|
}
|
|
2445
2607
|
function mapAppGit(value) {
|
|
@@ -3278,7 +3440,7 @@ function isoToNanoString(iso, fallback) {
|
|
|
3278
3440
|
return fallback;
|
|
3279
3441
|
}
|
|
3280
3442
|
}
|
|
3281
|
-
function enrichFromTranscript(payload, eventId, traceShipper) {
|
|
3443
|
+
function enrichFromTranscript(payload, eventId, traceShipper, promptTools) {
|
|
3282
3444
|
var _a, _b, _c, _d;
|
|
3283
3445
|
if (!payload.transcript_path) {
|
|
3284
3446
|
return { summary: void 0, props: {} };
|
|
@@ -3317,7 +3479,8 @@ function enrichFromTranscript(payload, eventId, traceShipper) {
|
|
|
3317
3479
|
attrString("ai.response.text", truncate(outputText)),
|
|
3318
3480
|
...toolCallNames ? [attrString("ai.toolCall.names", toolCallNames)] : [],
|
|
3319
3481
|
...phase.hasThinking ? [attrString("ai.has_thinking", "true")] : [],
|
|
3320
|
-
attrInt("ai.llm_call.index", emittedPhaseIndex)
|
|
3482
|
+
attrInt("ai.llm_call.index", emittedPhaseIndex),
|
|
3483
|
+
promptTools
|
|
3321
3484
|
]
|
|
3322
3485
|
});
|
|
3323
3486
|
emittedPhaseIndex++;
|
|
@@ -3339,7 +3502,8 @@ function enrichFromTranscript(payload, eventId, traceShipper) {
|
|
|
3339
3502
|
attrString("gen_ai.system", "anthropic"),
|
|
3340
3503
|
attrInt("gen_ai.usage.prompt_tokens", spanInputTokens),
|
|
3341
3504
|
attrInt("gen_ai.usage.completion_tokens", spanOutputTokens),
|
|
3342
|
-
...summary.lastTurnCacheReadTokens != null && summary.lastTurnCacheReadTokens > 0 ? [attrInt("gen_ai.usage.cache_read_tokens", summary.lastTurnCacheReadTokens)] : []
|
|
3505
|
+
...summary.lastTurnCacheReadTokens != null && summary.lastTurnCacheReadTokens > 0 ? [attrInt("gen_ai.usage.cache_read_tokens", summary.lastTurnCacheReadTokens)] : [],
|
|
3506
|
+
promptTools
|
|
3343
3507
|
]
|
|
3344
3508
|
});
|
|
3345
3509
|
}
|
|
@@ -3365,7 +3529,12 @@ function buildStopOutput(summary, lastAssistantMessage) {
|
|
|
3365
3529
|
return finalMessage;
|
|
3366
3530
|
}
|
|
3367
3531
|
async function handleStopOrFailure(payload, eventId, convoId, config, properties, eventShipper, traceShipper, extraProperties) {
|
|
3368
|
-
const { summary, props: transcriptProps } = enrichFromTranscript(
|
|
3532
|
+
const { summary, props: transcriptProps } = enrichFromTranscript(
|
|
3533
|
+
payload,
|
|
3534
|
+
eventId,
|
|
3535
|
+
traceShipper,
|
|
3536
|
+
promptToolsAttribute(resolvePromptTools({ override: config.tools }))
|
|
3537
|
+
);
|
|
3369
3538
|
const instructions = gatherInstructions(payload.session_id);
|
|
3370
3539
|
const appendSysPrompt = readAppendSystemPrompt(payload.session_id);
|
|
3371
3540
|
const output = buildStopOutput(summary, payload.last_assistant_message);
|
package/dist/index.d.cts
CHANGED
|
@@ -506,6 +506,32 @@ 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
|
declare class EventShipper extends EventShipper$1 {
|
|
511
537
|
constructor(opts: ConstructorParameters<typeof EventShipper$1>[0]);
|
|
@@ -543,6 +569,7 @@ interface ConfigFile {
|
|
|
543
569
|
custom_properties?: Record<string, unknown>;
|
|
544
570
|
self_diagnostics?: SelfDiagnosticsConfig;
|
|
545
571
|
app_git?: AppGitFileOptions | false;
|
|
572
|
+
tools?: unknown[];
|
|
546
573
|
}
|
|
547
574
|
interface RaindropConfig {
|
|
548
575
|
writeKey: string;
|
|
@@ -563,6 +590,11 @@ interface RaindropConfig {
|
|
|
563
590
|
selfDiagnostics?: SelfDiagnosticsConfig;
|
|
564
591
|
/** Application Git identity override. false disables enrichment. */
|
|
565
592
|
appGit?: AppGitOptions | false;
|
|
593
|
+
/**
|
|
594
|
+
* Tool catalog recorded as `ai.prompt.tools` on every LLM span. Hooks never
|
|
595
|
+
* see the model request, so this is the only way to record it.
|
|
596
|
+
*/
|
|
597
|
+
tools?: PromptToolsOverride;
|
|
566
598
|
}
|
|
567
599
|
/**
|
|
568
600
|
* Load config with precedence (low -> high):
|
|
@@ -610,6 +642,7 @@ interface MapperConfig {
|
|
|
610
642
|
debug: boolean;
|
|
611
643
|
eventName: string;
|
|
612
644
|
customProperties: Record<string, unknown>;
|
|
645
|
+
tools?: PromptToolsOverride;
|
|
613
646
|
}
|
|
614
647
|
declare function mapHookToRaindrop(payload: HookPayload, config: MapperConfig, eventShipper: EventShipper, traceShipper: TraceShipper): Promise<void>;
|
|
615
648
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -506,6 +506,32 @@ 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
|
declare class EventShipper extends EventShipper$1 {
|
|
511
537
|
constructor(opts: ConstructorParameters<typeof EventShipper$1>[0]);
|
|
@@ -543,6 +569,7 @@ interface ConfigFile {
|
|
|
543
569
|
custom_properties?: Record<string, unknown>;
|
|
544
570
|
self_diagnostics?: SelfDiagnosticsConfig;
|
|
545
571
|
app_git?: AppGitFileOptions | false;
|
|
572
|
+
tools?: unknown[];
|
|
546
573
|
}
|
|
547
574
|
interface RaindropConfig {
|
|
548
575
|
writeKey: string;
|
|
@@ -563,6 +590,11 @@ interface RaindropConfig {
|
|
|
563
590
|
selfDiagnostics?: SelfDiagnosticsConfig;
|
|
564
591
|
/** Application Git identity override. false disables enrichment. */
|
|
565
592
|
appGit?: AppGitOptions | false;
|
|
593
|
+
/**
|
|
594
|
+
* Tool catalog recorded as `ai.prompt.tools` on every LLM span. Hooks never
|
|
595
|
+
* see the model request, so this is the only way to record it.
|
|
596
|
+
*/
|
|
597
|
+
tools?: PromptToolsOverride;
|
|
566
598
|
}
|
|
567
599
|
/**
|
|
568
600
|
* Load config with precedence (low -> high):
|
|
@@ -610,6 +642,7 @@ interface MapperConfig {
|
|
|
610
642
|
debug: boolean;
|
|
611
643
|
eventName: string;
|
|
612
644
|
customProperties: Record<string, unknown>;
|
|
645
|
+
tools?: PromptToolsOverride;
|
|
613
646
|
}
|
|
614
647
|
declare function mapHookToRaindrop(payload: HookPayload, config: MapperConfig, eventShipper: EventShipper, traceShipper: TraceShipper): Promise<void>;
|
|
615
648
|
/**
|
package/dist/index.js
CHANGED
|
@@ -60,7 +60,7 @@ function evalScopeAttributes() {
|
|
|
60
60
|
return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
// ../core/dist/chunk-
|
|
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;
|
|
@@ -2047,6 +2047,158 @@ var TraceShipper = class {
|
|
|
2047
2047
|
}
|
|
2048
2048
|
}
|
|
2049
2049
|
};
|
|
2050
|
+
var PROMPT_TOOLS_ATTRIBUTE = "ai.prompt.tools";
|
|
2051
|
+
function isRecord(value) {
|
|
2052
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2053
|
+
}
|
|
2054
|
+
var JSON_SCHEMA_KEYS = [
|
|
2055
|
+
"type",
|
|
2056
|
+
"properties",
|
|
2057
|
+
"$schema",
|
|
2058
|
+
"$ref",
|
|
2059
|
+
"anyOf",
|
|
2060
|
+
"oneOf",
|
|
2061
|
+
"allOf",
|
|
2062
|
+
"enum",
|
|
2063
|
+
"const",
|
|
2064
|
+
"items",
|
|
2065
|
+
"additionalProperties",
|
|
2066
|
+
"required"
|
|
2067
|
+
];
|
|
2068
|
+
function isJsonSchema(value) {
|
|
2069
|
+
if (!isRecord(value)) return false;
|
|
2070
|
+
if (typeof value["~standard"] === "object") return false;
|
|
2071
|
+
if (isRecord(value._def) || isRecord(value._zod)) return false;
|
|
2072
|
+
if (Object.keys(value).length === 0) return true;
|
|
2073
|
+
return JSON_SCHEMA_KEYS.some((key) => key in value);
|
|
2074
|
+
}
|
|
2075
|
+
function toJsonSchema(value, options) {
|
|
2076
|
+
if (value === void 0 || value === null) return void 0;
|
|
2077
|
+
if (isJsonSchema(value)) return value;
|
|
2078
|
+
if (isRecord(value) && isJsonSchema(value.jsonSchema)) return value.jsonSchema;
|
|
2079
|
+
if (isRecord(value) && isJsonSchema(value.json)) return value.json;
|
|
2080
|
+
if (options == null ? void 0 : options.schema) {
|
|
2081
|
+
try {
|
|
2082
|
+
return options.schema(value);
|
|
2083
|
+
} catch (e) {
|
|
2084
|
+
return void 0;
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
return void 0;
|
|
2088
|
+
}
|
|
2089
|
+
function pickString(value) {
|
|
2090
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
2091
|
+
}
|
|
2092
|
+
function functionTool(name, description, schema, options) {
|
|
2093
|
+
const tool = { type: "function", name };
|
|
2094
|
+
const desc = pickString(description);
|
|
2095
|
+
if (desc !== void 0) tool.description = desc;
|
|
2096
|
+
const inputSchema = toJsonSchema(schema, options);
|
|
2097
|
+
if (inputSchema !== void 0) tool.inputSchema = inputSchema;
|
|
2098
|
+
return tool;
|
|
2099
|
+
}
|
|
2100
|
+
function normalizeToolDeclaration(tool, options, fallbackName) {
|
|
2101
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
2102
|
+
if (!isRecord(tool)) return void 0;
|
|
2103
|
+
if (tool.type === "provider-defined" || tool.type === "provider") {
|
|
2104
|
+
const name2 = (_b = (_a = pickString(tool.name)) != null ? _a : pickString(tool.id)) != null ? _b : fallbackName;
|
|
2105
|
+
if (name2 === void 0) return void 0;
|
|
2106
|
+
const declaration = { type: "provider-defined", name: name2 };
|
|
2107
|
+
const id = pickString(tool.id);
|
|
2108
|
+
if (id !== void 0) declaration.id = id;
|
|
2109
|
+
if (isRecord(tool.args)) declaration.args = tool.args;
|
|
2110
|
+
return declaration;
|
|
2111
|
+
}
|
|
2112
|
+
if (isRecord(tool.toolSpec)) {
|
|
2113
|
+
const spec = tool.toolSpec;
|
|
2114
|
+
const name2 = (_c = pickString(spec.name)) != null ? _c : fallbackName;
|
|
2115
|
+
if (name2 === void 0) return void 0;
|
|
2116
|
+
return functionTool(name2, spec.description, spec.inputSchema, options);
|
|
2117
|
+
}
|
|
2118
|
+
if (isRecord(tool.function)) {
|
|
2119
|
+
const fn = tool.function;
|
|
2120
|
+
const name2 = (_d = pickString(fn.name)) != null ? _d : fallbackName;
|
|
2121
|
+
if (name2 === void 0) return void 0;
|
|
2122
|
+
return functionTool(name2, fn.description, (_e = fn.parameters) != null ? _e : fn.input_schema, options);
|
|
2123
|
+
}
|
|
2124
|
+
const name = (_g = (_f = pickString(tool.name)) != null ? _f : pickString(tool.id)) != null ? _g : fallbackName;
|
|
2125
|
+
if (name === void 0) return void 0;
|
|
2126
|
+
const type = pickString(tool.type);
|
|
2127
|
+
if (type !== void 0 && type !== "function" && type !== "dynamic" && type !== "custom") {
|
|
2128
|
+
if (!("input_schema" in tool) && !("inputSchema" in tool) && !("parameters" in tool)) {
|
|
2129
|
+
return { type: "provider-defined", id: type, name };
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
return functionTool(
|
|
2133
|
+
name,
|
|
2134
|
+
tool.description,
|
|
2135
|
+
(_j = (_i = (_h = tool.inputSchema) != null ? _h : tool.input_schema) != null ? _i : tool.parameters) != null ? _j : tool.schema,
|
|
2136
|
+
options
|
|
2137
|
+
);
|
|
2138
|
+
}
|
|
2139
|
+
var NOT_A_GEMINI_GROUP_KEYS = ["name", "id", "type", "function", "toolSpec", "cachePoint"];
|
|
2140
|
+
function isGeminiToolGroup(tool) {
|
|
2141
|
+
if (Array.isArray(tool.functionDeclarations)) return true;
|
|
2142
|
+
const keys = Object.keys(tool);
|
|
2143
|
+
if (keys.length === 0 || NOT_A_GEMINI_GROUP_KEYS.some((key) => key in tool)) return false;
|
|
2144
|
+
return keys.every((key) => isRecord(tool[key]));
|
|
2145
|
+
}
|
|
2146
|
+
function expandGeminiTool(tool, options) {
|
|
2147
|
+
const declarations = [];
|
|
2148
|
+
for (const [key, value] of Object.entries(tool)) {
|
|
2149
|
+
if (key === "functionDeclarations" && Array.isArray(value)) {
|
|
2150
|
+
for (const declaration of value) {
|
|
2151
|
+
const normalized = normalizeToolDeclaration(declaration, options);
|
|
2152
|
+
if (normalized) declarations.push(normalized);
|
|
2153
|
+
}
|
|
2154
|
+
} else if (isRecord(value)) {
|
|
2155
|
+
declarations.push({ type: "provider-defined", id: key, name: key, args: value });
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
return declarations;
|
|
2159
|
+
}
|
|
2160
|
+
function normalizeToolDeclarations(tools, options) {
|
|
2161
|
+
if (tools === void 0 || tools === null) return void 0;
|
|
2162
|
+
if (Array.isArray(tools)) {
|
|
2163
|
+
return tools.flatMap((tool) => {
|
|
2164
|
+
if (isRecord(tool) && isGeminiToolGroup(tool)) {
|
|
2165
|
+
return expandGeminiTool(tool, options);
|
|
2166
|
+
}
|
|
2167
|
+
const declaration = normalizeToolDeclaration(tool, options);
|
|
2168
|
+
return declaration ? [declaration] : [];
|
|
2169
|
+
});
|
|
2170
|
+
}
|
|
2171
|
+
if (!isRecord(tools)) return void 0;
|
|
2172
|
+
return Object.entries(tools).flatMap(([key, tool]) => {
|
|
2173
|
+
const declaration = normalizeToolDeclaration(tool, options, key);
|
|
2174
|
+
return declaration ? [declaration] : [];
|
|
2175
|
+
});
|
|
2176
|
+
}
|
|
2177
|
+
function resolvePromptTools(args) {
|
|
2178
|
+
var _a;
|
|
2179
|
+
if (args.override !== void 0) {
|
|
2180
|
+
return (_a = normalizeToolDeclarations(args.override, args.options)) != null ? _a : [];
|
|
2181
|
+
}
|
|
2182
|
+
return normalizeToolDeclarations(args.inferred, args.options);
|
|
2183
|
+
}
|
|
2184
|
+
function promptToolsAttribute(tools) {
|
|
2185
|
+
const values = promptToolsAttributeValue(tools);
|
|
2186
|
+
if (values === void 0) return void 0;
|
|
2187
|
+
return {
|
|
2188
|
+
key: PROMPT_TOOLS_ATTRIBUTE,
|
|
2189
|
+
value: { arrayValue: { values: values.map((stringValue) => ({ stringValue })) } }
|
|
2190
|
+
};
|
|
2191
|
+
}
|
|
2192
|
+
function promptToolsAttributeValue(tools) {
|
|
2193
|
+
if (tools === void 0) return void 0;
|
|
2194
|
+
return tools.map((tool) => {
|
|
2195
|
+
try {
|
|
2196
|
+
return JSON.stringify(tool);
|
|
2197
|
+
} catch (e) {
|
|
2198
|
+
return JSON.stringify({ type: tool.type, name: tool.name });
|
|
2199
|
+
}
|
|
2200
|
+
});
|
|
2201
|
+
}
|
|
2050
2202
|
|
|
2051
2203
|
// ../core/dist/index.node.js
|
|
2052
2204
|
import { AsyncLocalStorage } from "async_hooks";
|
|
@@ -2225,7 +2377,7 @@ installTracingSuppressionHook();
|
|
|
2225
2377
|
// package.json
|
|
2226
2378
|
var package_default = {
|
|
2227
2379
|
name: "@raindrop-ai/claude-code",
|
|
2228
|
-
version: "0.0.
|
|
2380
|
+
version: "0.0.21",
|
|
2229
2381
|
description: "Raindrop observability for Claude Code CLI \u2014 automatic session, tool call, and prompt tracing via hooks",
|
|
2230
2382
|
license: "MIT",
|
|
2231
2383
|
homepage: "https://www.raindrop.ai/docs/integrations/claude-code/",
|
|
@@ -2365,6 +2517,15 @@ function loadConfig() {
|
|
|
2365
2517
|
} catch (e) {
|
|
2366
2518
|
}
|
|
2367
2519
|
}
|
|
2520
|
+
let tools = Array.isArray(file.tools) ? file.tools : void 0;
|
|
2521
|
+
const envTools = process.env["RAINDROP_TOOLS"];
|
|
2522
|
+
if (envTools) {
|
|
2523
|
+
try {
|
|
2524
|
+
const parsed = JSON.parse(envTools);
|
|
2525
|
+
if (Array.isArray(parsed)) tools = parsed;
|
|
2526
|
+
} catch (e) {
|
|
2527
|
+
}
|
|
2528
|
+
}
|
|
2368
2529
|
let selfDiagnostics = file.self_diagnostics;
|
|
2369
2530
|
const envDiag = process.env["RAINDROP_SELF_DIAGNOSTICS"];
|
|
2370
2531
|
if (envDiag) {
|
|
@@ -2393,7 +2554,8 @@ function loadConfig() {
|
|
|
2393
2554
|
eventName: (_l = (_k = process.env["RAINDROP_EVENT_NAME"]) != null ? _k : file.event_name) != null ? _l : "claude_code_session",
|
|
2394
2555
|
customProperties,
|
|
2395
2556
|
selfDiagnostics,
|
|
2396
|
-
appGit: mapAppGit(file.app_git)
|
|
2557
|
+
appGit: mapAppGit(file.app_git),
|
|
2558
|
+
tools
|
|
2397
2559
|
};
|
|
2398
2560
|
}
|
|
2399
2561
|
function mapAppGit(value) {
|
|
@@ -3232,7 +3394,7 @@ function isoToNanoString(iso, fallback) {
|
|
|
3232
3394
|
return fallback;
|
|
3233
3395
|
}
|
|
3234
3396
|
}
|
|
3235
|
-
function enrichFromTranscript(payload, eventId, traceShipper) {
|
|
3397
|
+
function enrichFromTranscript(payload, eventId, traceShipper, promptTools) {
|
|
3236
3398
|
var _a, _b, _c, _d;
|
|
3237
3399
|
if (!payload.transcript_path) {
|
|
3238
3400
|
return { summary: void 0, props: {} };
|
|
@@ -3271,7 +3433,8 @@ function enrichFromTranscript(payload, eventId, traceShipper) {
|
|
|
3271
3433
|
attrString("ai.response.text", truncate(outputText)),
|
|
3272
3434
|
...toolCallNames ? [attrString("ai.toolCall.names", toolCallNames)] : [],
|
|
3273
3435
|
...phase.hasThinking ? [attrString("ai.has_thinking", "true")] : [],
|
|
3274
|
-
attrInt("ai.llm_call.index", emittedPhaseIndex)
|
|
3436
|
+
attrInt("ai.llm_call.index", emittedPhaseIndex),
|
|
3437
|
+
promptTools
|
|
3275
3438
|
]
|
|
3276
3439
|
});
|
|
3277
3440
|
emittedPhaseIndex++;
|
|
@@ -3293,7 +3456,8 @@ function enrichFromTranscript(payload, eventId, traceShipper) {
|
|
|
3293
3456
|
attrString("gen_ai.system", "anthropic"),
|
|
3294
3457
|
attrInt("gen_ai.usage.prompt_tokens", spanInputTokens),
|
|
3295
3458
|
attrInt("gen_ai.usage.completion_tokens", spanOutputTokens),
|
|
3296
|
-
...summary.lastTurnCacheReadTokens != null && summary.lastTurnCacheReadTokens > 0 ? [attrInt("gen_ai.usage.cache_read_tokens", summary.lastTurnCacheReadTokens)] : []
|
|
3459
|
+
...summary.lastTurnCacheReadTokens != null && summary.lastTurnCacheReadTokens > 0 ? [attrInt("gen_ai.usage.cache_read_tokens", summary.lastTurnCacheReadTokens)] : [],
|
|
3460
|
+
promptTools
|
|
3297
3461
|
]
|
|
3298
3462
|
});
|
|
3299
3463
|
}
|
|
@@ -3319,7 +3483,12 @@ function buildStopOutput(summary, lastAssistantMessage) {
|
|
|
3319
3483
|
return finalMessage;
|
|
3320
3484
|
}
|
|
3321
3485
|
async function handleStopOrFailure(payload, eventId, convoId, config, properties, eventShipper, traceShipper, extraProperties) {
|
|
3322
|
-
const { summary, props: transcriptProps } = enrichFromTranscript(
|
|
3486
|
+
const { summary, props: transcriptProps } = enrichFromTranscript(
|
|
3487
|
+
payload,
|
|
3488
|
+
eventId,
|
|
3489
|
+
traceShipper,
|
|
3490
|
+
promptToolsAttribute(resolvePromptTools({ override: config.tools }))
|
|
3491
|
+
);
|
|
3323
3492
|
const instructions = gatherInstructions(payload.session_id);
|
|
3324
3493
|
const appendSysPrompt = readAppendSystemPrompt(payload.session_id);
|
|
3325
3494
|
const output = buildStopOutput(summary, payload.last_assistant_message);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raindrop-ai/claude-code",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.21",
|
|
4
4
|
"description": "Raindrop observability for Claude Code CLI — automatic session, tool call, and prompt tracing via hooks",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://www.raindrop.ai/docs/integrations/claude-code/",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"tsup": "^8.4.0",
|
|
54
54
|
"typescript": "^5.3.3",
|
|
55
55
|
"vitest": "^2.1.0",
|
|
56
|
-
"@raindrop-ai/core": "0.3.
|
|
56
|
+
"@raindrop-ai/core": "0.3.1"
|
|
57
57
|
},
|
|
58
58
|
"publishConfig": {
|
|
59
59
|
"access": "public"
|