@raindrop-ai/opencode-plugin 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/dist/{chunk-FCORH4YS.js → chunk-ZG47FVK7.js} +251 -9
- package/dist/index.cjs +279 -16
- package/dist/index.d.cts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +33 -8
- package/dist/{self-diagnostics-NiAq-SZ8.d.cts → self-diagnostics-CLW6h4zB.d.cts} +27 -1
- package/dist/{self-diagnostics-NiAq-SZ8.d.ts → self-diagnostics-CLW6h4zB.d.ts} +27 -1
- package/dist/v2.cjs +283 -20
- package/dist/v2.d.cts +7 -2
- package/dist/v2.d.ts +7 -2
- package/dist/v2.js +37 -12
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -33,6 +33,61 @@ rejected at the ingest size limit. Hook error logs are rate-limited to one
|
|
|
33
33
|
line per failure family per 30s so a persistent error can't flood the host's
|
|
34
34
|
output.
|
|
35
35
|
|
|
36
|
+
## Tool catalog capture (`ai.prompt.tools`)
|
|
37
|
+
|
|
38
|
+
OpenCode's step events carry no tool list, so the plugin cannot see the exact
|
|
39
|
+
tools each model request was given. Instead it records the host's tool catalog
|
|
40
|
+
for the step's model:
|
|
41
|
+
|
|
42
|
+
- **v1 plugin (`@raindrop-ai/opencode-plugin`)**: on the first step of a
|
|
43
|
+
session for a given provider/model, the plugin calls
|
|
44
|
+
`client.tool.list({ query: { provider, model } })` (OpenCode's experimental
|
|
45
|
+
`/experimental/tool` endpoint) once, caches the answer per session and
|
|
46
|
+
model, and stamps it as `ai.prompt.tools` on every step span. The lookup is
|
|
47
|
+
deduplicated while in flight, bounded by a 2s timeout, and never surfaces
|
|
48
|
+
errors to OpenCode: when it fails, the attribute is simply absent.
|
|
49
|
+
- **v2 plugin (`@raindrop-ai/opencode-plugin/v2`)**: the v2 host has no
|
|
50
|
+
per-model catalog endpoint; the plugin reads the registered tool list
|
|
51
|
+
(`ctx.tool.list()`, after every plugin's `tool.transform`) with the same
|
|
52
|
+
caching, timeout and no-throw rules.
|
|
53
|
+
|
|
54
|
+
Because this is OpenCode's catalog for that model, not the exact per-request
|
|
55
|
+
set, catalog-derived spans also carry `ai.prompt.tools.source = "opencode.tool.list"`.
|
|
56
|
+
An explicit override (below) is exact and carries no `source`. Each element of
|
|
57
|
+
`ai.prompt.tools` is a JSON document
|
|
58
|
+
`{"type":"function","name":…,"description"?:…,"inputSchema"?:<JSON Schema>}`;
|
|
59
|
+
a tool whose schema is not plain JSON Schema is recorded without `inputSchema`
|
|
60
|
+
rather than with an invented one. The plugin has no separate content switch
|
|
61
|
+
(prompts and responses are always recorded; only the system prompt is opt-in),
|
|
62
|
+
so the catalog is recorded whenever tracing is on. Absent attribute = catalog
|
|
63
|
+
unknown; `[]` = no tools.
|
|
64
|
+
|
|
65
|
+
### `tools` override
|
|
66
|
+
|
|
67
|
+
Overrides the tool catalog recorded as `ai.prompt.tools` on every model span.
|
|
68
|
+
Use when the integration cannot see the tools the model was given. The
|
|
69
|
+
override replaces the catalog entirely (`tools: []` records an empty catalog)
|
|
70
|
+
and skips the catalog lookup.
|
|
71
|
+
|
|
72
|
+
`raindrop.json` (user- or project-level):
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"tools": [
|
|
77
|
+
{
|
|
78
|
+
"name": "get_weather",
|
|
79
|
+
"description": "Get the current weather",
|
|
80
|
+
"parameters": { "type": "object", "properties": { "city": { "type": "string" } }, "required": ["city"] }
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Programmatic options (v1 `plugin(input, { tools })`, v2 `raindrop({ tools })`)
|
|
87
|
+
take precedence over the config file. Any recognized declaration shape is
|
|
88
|
+
accepted (OpenAI `{type:"function",function:{…}}`, Anthropic `input_schema`,
|
|
89
|
+
plain `{name, description, parameters}`, …).
|
|
90
|
+
|
|
36
91
|
## Correlating per-message feedback signals
|
|
37
92
|
|
|
38
93
|
Each Raindrop event uses a client-generated `event_id` that isn't predictable
|
|
@@ -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;
|
|
@@ -2069,6 +2069,151 @@ var TraceShipper = class {
|
|
|
2069
2069
|
}
|
|
2070
2070
|
}
|
|
2071
2071
|
};
|
|
2072
|
+
var PROMPT_TOOLS_ATTRIBUTE = "ai.prompt.tools";
|
|
2073
|
+
function isRecord(value) {
|
|
2074
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2075
|
+
}
|
|
2076
|
+
var JSON_SCHEMA_KEYS = [
|
|
2077
|
+
"type",
|
|
2078
|
+
"properties",
|
|
2079
|
+
"$schema",
|
|
2080
|
+
"$ref",
|
|
2081
|
+
"anyOf",
|
|
2082
|
+
"oneOf",
|
|
2083
|
+
"allOf",
|
|
2084
|
+
"enum",
|
|
2085
|
+
"const",
|
|
2086
|
+
"items",
|
|
2087
|
+
"additionalProperties",
|
|
2088
|
+
"required"
|
|
2089
|
+
];
|
|
2090
|
+
function isJsonSchema(value) {
|
|
2091
|
+
if (!isRecord(value)) return false;
|
|
2092
|
+
if (typeof value["~standard"] === "object") return false;
|
|
2093
|
+
if (isRecord(value._def) || isRecord(value._zod)) return false;
|
|
2094
|
+
if (Object.keys(value).length === 0) return true;
|
|
2095
|
+
return JSON_SCHEMA_KEYS.some((key) => key in value);
|
|
2096
|
+
}
|
|
2097
|
+
function toJsonSchema(value, options) {
|
|
2098
|
+
if (value === void 0 || value === null) return void 0;
|
|
2099
|
+
if (isJsonSchema(value)) return value;
|
|
2100
|
+
if (isRecord(value) && isJsonSchema(value.jsonSchema)) return value.jsonSchema;
|
|
2101
|
+
if (isRecord(value) && isJsonSchema(value.json)) return value.json;
|
|
2102
|
+
if (options == null ? void 0 : options.schema) {
|
|
2103
|
+
try {
|
|
2104
|
+
return options.schema(value);
|
|
2105
|
+
} catch (e) {
|
|
2106
|
+
return void 0;
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
return void 0;
|
|
2110
|
+
}
|
|
2111
|
+
function pickString(value) {
|
|
2112
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
2113
|
+
}
|
|
2114
|
+
function functionTool(name, description, schema, options) {
|
|
2115
|
+
const tool = { type: "function", name };
|
|
2116
|
+
const desc = pickString(description);
|
|
2117
|
+
if (desc !== void 0) tool.description = desc;
|
|
2118
|
+
const inputSchema = toJsonSchema(schema, options);
|
|
2119
|
+
if (inputSchema !== void 0) tool.inputSchema = inputSchema;
|
|
2120
|
+
return tool;
|
|
2121
|
+
}
|
|
2122
|
+
function normalizeToolDeclaration(tool, options, fallbackName) {
|
|
2123
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
2124
|
+
if (!isRecord(tool)) return void 0;
|
|
2125
|
+
if (tool.type === "provider-defined" || tool.type === "provider") {
|
|
2126
|
+
const name2 = (_b = (_a = pickString(tool.name)) != null ? _a : pickString(tool.id)) != null ? _b : fallbackName;
|
|
2127
|
+
if (name2 === void 0) return void 0;
|
|
2128
|
+
const declaration = { type: "provider-defined", name: name2 };
|
|
2129
|
+
const id = pickString(tool.id);
|
|
2130
|
+
if (id !== void 0) declaration.id = id;
|
|
2131
|
+
if (isRecord(tool.args)) declaration.args = tool.args;
|
|
2132
|
+
return declaration;
|
|
2133
|
+
}
|
|
2134
|
+
if (isRecord(tool.toolSpec)) {
|
|
2135
|
+
const spec = tool.toolSpec;
|
|
2136
|
+
const name2 = (_c = pickString(spec.name)) != null ? _c : fallbackName;
|
|
2137
|
+
if (name2 === void 0) return void 0;
|
|
2138
|
+
return functionTool(name2, spec.description, spec.inputSchema, options);
|
|
2139
|
+
}
|
|
2140
|
+
if (isRecord(tool.function)) {
|
|
2141
|
+
const fn = tool.function;
|
|
2142
|
+
const name2 = (_d = pickString(fn.name)) != null ? _d : fallbackName;
|
|
2143
|
+
if (name2 === void 0) return void 0;
|
|
2144
|
+
return functionTool(name2, fn.description, (_e = fn.parameters) != null ? _e : fn.input_schema, options);
|
|
2145
|
+
}
|
|
2146
|
+
const name = (_g = (_f = pickString(tool.name)) != null ? _f : pickString(tool.id)) != null ? _g : fallbackName;
|
|
2147
|
+
if (name === void 0) return void 0;
|
|
2148
|
+
const type = pickString(tool.type);
|
|
2149
|
+
if (type !== void 0 && type !== "function" && type !== "dynamic" && type !== "custom") {
|
|
2150
|
+
if (!("input_schema" in tool) && !("inputSchema" in tool) && !("parameters" in tool)) {
|
|
2151
|
+
return { type: "provider-defined", id: type, name };
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
return functionTool(
|
|
2155
|
+
name,
|
|
2156
|
+
tool.description,
|
|
2157
|
+
(_j = (_i = (_h = tool.inputSchema) != null ? _h : tool.input_schema) != null ? _i : tool.parameters) != null ? _j : tool.schema,
|
|
2158
|
+
options
|
|
2159
|
+
);
|
|
2160
|
+
}
|
|
2161
|
+
var NOT_A_GEMINI_GROUP_KEYS = ["name", "id", "type", "function", "toolSpec", "cachePoint"];
|
|
2162
|
+
function isGeminiToolGroup(tool) {
|
|
2163
|
+
if (Array.isArray(tool.functionDeclarations)) return true;
|
|
2164
|
+
const keys = Object.keys(tool);
|
|
2165
|
+
if (keys.length === 0 || NOT_A_GEMINI_GROUP_KEYS.some((key) => key in tool)) return false;
|
|
2166
|
+
return keys.every((key) => isRecord(tool[key]));
|
|
2167
|
+
}
|
|
2168
|
+
function expandGeminiTool(tool, options) {
|
|
2169
|
+
const declarations = [];
|
|
2170
|
+
for (const [key, value] of Object.entries(tool)) {
|
|
2171
|
+
if (key === "functionDeclarations" && Array.isArray(value)) {
|
|
2172
|
+
for (const declaration of value) {
|
|
2173
|
+
const normalized = normalizeToolDeclaration(declaration, options);
|
|
2174
|
+
if (normalized) declarations.push(normalized);
|
|
2175
|
+
}
|
|
2176
|
+
} else if (isRecord(value)) {
|
|
2177
|
+
declarations.push({ type: "provider-defined", id: key, name: key, args: value });
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
return declarations;
|
|
2181
|
+
}
|
|
2182
|
+
function normalizeToolDeclarations(tools, options) {
|
|
2183
|
+
if (tools === void 0 || tools === null) return void 0;
|
|
2184
|
+
if (Array.isArray(tools)) {
|
|
2185
|
+
return tools.flatMap((tool) => {
|
|
2186
|
+
if (isRecord(tool) && isGeminiToolGroup(tool)) {
|
|
2187
|
+
return expandGeminiTool(tool, options);
|
|
2188
|
+
}
|
|
2189
|
+
const declaration = normalizeToolDeclaration(tool, options);
|
|
2190
|
+
return declaration ? [declaration] : [];
|
|
2191
|
+
});
|
|
2192
|
+
}
|
|
2193
|
+
if (!isRecord(tools)) return void 0;
|
|
2194
|
+
return Object.entries(tools).flatMap(([key, tool]) => {
|
|
2195
|
+
const declaration = normalizeToolDeclaration(tool, options, key);
|
|
2196
|
+
return declaration ? [declaration] : [];
|
|
2197
|
+
});
|
|
2198
|
+
}
|
|
2199
|
+
function promptToolsAttribute(tools) {
|
|
2200
|
+
const values = promptToolsAttributeValue(tools);
|
|
2201
|
+
if (values === void 0) return void 0;
|
|
2202
|
+
return {
|
|
2203
|
+
key: PROMPT_TOOLS_ATTRIBUTE,
|
|
2204
|
+
value: { arrayValue: { values: values.map((stringValue) => ({ stringValue })) } }
|
|
2205
|
+
};
|
|
2206
|
+
}
|
|
2207
|
+
function promptToolsAttributeValue(tools) {
|
|
2208
|
+
if (tools === void 0) return void 0;
|
|
2209
|
+
return tools.map((tool) => {
|
|
2210
|
+
try {
|
|
2211
|
+
return JSON.stringify(tool);
|
|
2212
|
+
} catch (e) {
|
|
2213
|
+
return JSON.stringify({ type: tool.type, name: tool.name });
|
|
2214
|
+
}
|
|
2215
|
+
});
|
|
2216
|
+
}
|
|
2072
2217
|
|
|
2073
2218
|
// ../core/dist/index.node.js
|
|
2074
2219
|
import { AsyncLocalStorage } from "async_hooks";
|
|
@@ -2283,15 +2428,16 @@ function loadConfig(projectDirectory) {
|
|
|
2283
2428
|
eventMetadata,
|
|
2284
2429
|
localWorkshopUrl: resolveLocalWorkshopUrl(merged.local_workshop_url),
|
|
2285
2430
|
appGit: mapAppGit(merged.app_git),
|
|
2286
|
-
selfDiagnostics: mapSelfDiagnostics(merged.self_diagnostics)
|
|
2431
|
+
selfDiagnostics: mapSelfDiagnostics(merged.self_diagnostics),
|
|
2432
|
+
tools: Array.isArray(merged.tools) ? merged.tools : void 0
|
|
2287
2433
|
};
|
|
2288
2434
|
}
|
|
2289
|
-
function
|
|
2435
|
+
function isRecord2(value) {
|
|
2290
2436
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2291
2437
|
}
|
|
2292
2438
|
function mapSelfDiagnostics(value) {
|
|
2293
2439
|
const env = process.env["RAINDROP_SELF_DIAGNOSTICS"];
|
|
2294
|
-
const record =
|
|
2440
|
+
const record = isRecord2(value) ? value : {};
|
|
2295
2441
|
const enabled = env !== void 0 ? env === "true" : typeof record["enabled"] === "boolean" ? record["enabled"] : void 0;
|
|
2296
2442
|
const signals = mapSelfDiagnosticsSignals(record["signals"]);
|
|
2297
2443
|
const options = {
|
|
@@ -2303,10 +2449,10 @@ function mapSelfDiagnostics(value) {
|
|
|
2303
2449
|
return Object.keys(options).length > 0 ? options : void 0;
|
|
2304
2450
|
}
|
|
2305
2451
|
function mapSelfDiagnosticsSignals(value) {
|
|
2306
|
-
if (!
|
|
2452
|
+
if (!isRecord2(value)) return void 0;
|
|
2307
2453
|
const out = {};
|
|
2308
2454
|
for (const [key, entry] of Object.entries(value)) {
|
|
2309
|
-
if (!
|
|
2455
|
+
if (!isRecord2(entry)) continue;
|
|
2310
2456
|
const definition = entry;
|
|
2311
2457
|
if (typeof definition["description"] !== "string") continue;
|
|
2312
2458
|
const sentiment = definition["sentiment"];
|
|
@@ -2343,7 +2489,7 @@ function resolveLocalWorkshopUrl(fileValue) {
|
|
|
2343
2489
|
// package.json
|
|
2344
2490
|
var package_default = {
|
|
2345
2491
|
name: "@raindrop-ai/opencode-plugin",
|
|
2346
|
-
version: "0.3.
|
|
2492
|
+
version: "0.3.1",
|
|
2347
2493
|
description: "Raindrop observability plugin for OpenCode \u2014 automatic session/event/span tracing",
|
|
2348
2494
|
type: "module",
|
|
2349
2495
|
main: "dist/index.js",
|
|
@@ -2553,13 +2699,13 @@ function selfDiagnosticsInputJsonSchema(config) {
|
|
|
2553
2699
|
additionalProperties: false
|
|
2554
2700
|
};
|
|
2555
2701
|
}
|
|
2556
|
-
function
|
|
2702
|
+
function isRecord3(value) {
|
|
2557
2703
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2558
2704
|
}
|
|
2559
2705
|
async function trackSelfDiagnosticsSignal(toolInput, config, eventShipper, eventId, debug) {
|
|
2560
2706
|
var _a, _b;
|
|
2561
2707
|
try {
|
|
2562
|
-
const input =
|
|
2708
|
+
const input = isRecord3(toolInput) ? toolInput : void 0;
|
|
2563
2709
|
const fallbackCategory = (_a = config.signalKeys[0]) != null ? _a : "unknown";
|
|
2564
2710
|
const categoryCandidate = normalizeString(input == null ? void 0 : input["category"]);
|
|
2565
2711
|
const category = categoryCandidate && config.signalKeySet.has(categoryCandidate) ? categoryCandidate : fallbackCategory;
|
|
@@ -2646,6 +2792,100 @@ var TraceShipper3 = class extends TraceShipper2 {
|
|
|
2646
2792
|
}
|
|
2647
2793
|
};
|
|
2648
2794
|
|
|
2795
|
+
// src/tool-catalog.ts
|
|
2796
|
+
var PROMPT_TOOLS_SOURCE_ATTRIBUTE = "ai.prompt.tools.source";
|
|
2797
|
+
var OPENCODE_TOOL_LIST_SOURCE = "opencode.tool.list";
|
|
2798
|
+
var TOOL_CATALOG_TIMEOUT_MS = 2e3;
|
|
2799
|
+
function isRecord4(value) {
|
|
2800
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2801
|
+
}
|
|
2802
|
+
function catalogItems(raw) {
|
|
2803
|
+
var _a;
|
|
2804
|
+
const list = Array.isArray(raw) ? raw : isRecord4(raw) && Array.isArray(raw.data) ? raw.data : void 0;
|
|
2805
|
+
if (!list) return void 0;
|
|
2806
|
+
const items = [];
|
|
2807
|
+
for (const item of list) {
|
|
2808
|
+
if (!isRecord4(item)) continue;
|
|
2809
|
+
const name = typeof item.id === "string" ? item.id : typeof item.name === "string" ? item.name : void 0;
|
|
2810
|
+
if (!name) continue;
|
|
2811
|
+
const schema = (_a = item.parameters) != null ? _a : item.input;
|
|
2812
|
+
items.push({
|
|
2813
|
+
type: "function",
|
|
2814
|
+
name,
|
|
2815
|
+
...typeof item.description === "string" ? { description: item.description } : {},
|
|
2816
|
+
...isJsonSchema(schema) ? { inputSchema: schema } : {}
|
|
2817
|
+
});
|
|
2818
|
+
}
|
|
2819
|
+
return items;
|
|
2820
|
+
}
|
|
2821
|
+
function withTimeout(promise, ms) {
|
|
2822
|
+
return new Promise((resolve2) => {
|
|
2823
|
+
const timer = setTimeout(() => resolve2(void 0), ms);
|
|
2824
|
+
if (typeof timer === "object" && "unref" in timer) timer.unref();
|
|
2825
|
+
promise.then(
|
|
2826
|
+
(value) => {
|
|
2827
|
+
clearTimeout(timer);
|
|
2828
|
+
resolve2(value);
|
|
2829
|
+
},
|
|
2830
|
+
() => {
|
|
2831
|
+
clearTimeout(timer);
|
|
2832
|
+
resolve2(void 0);
|
|
2833
|
+
}
|
|
2834
|
+
);
|
|
2835
|
+
});
|
|
2836
|
+
}
|
|
2837
|
+
function createToolCatalog(options = {}) {
|
|
2838
|
+
var _a, _b;
|
|
2839
|
+
const override = options.override !== void 0 ? { tools: (_a = normalizeToolDeclarations(options.override)) != null ? _a : [] } : void 0;
|
|
2840
|
+
const timeoutMs = (_b = options.timeoutMs) != null ? _b : TOOL_CATALOG_TIMEOUT_MS;
|
|
2841
|
+
const cache = /* @__PURE__ */ new Map();
|
|
2842
|
+
async function lookup(query) {
|
|
2843
|
+
const fetch2 = options.fetch;
|
|
2844
|
+
if (!fetch2) return void 0;
|
|
2845
|
+
let raw;
|
|
2846
|
+
try {
|
|
2847
|
+
raw = await withTimeout(Promise.resolve().then(() => fetch2(query)), timeoutMs);
|
|
2848
|
+
} catch (error) {
|
|
2849
|
+
if (options.debug) console.log(`[raindrop-ai/opencode-plugin] tool catalog lookup failed: ${String(error)}`);
|
|
2850
|
+
return void 0;
|
|
2851
|
+
}
|
|
2852
|
+
const tools = normalizeToolDeclarations(catalogItems(raw));
|
|
2853
|
+
if (!tools) {
|
|
2854
|
+
if (options.debug) console.log("[raindrop-ai/opencode-plugin] tool catalog lookup returned no tool list");
|
|
2855
|
+
return void 0;
|
|
2856
|
+
}
|
|
2857
|
+
return { tools, source: OPENCODE_TOOL_LIST_SOURCE };
|
|
2858
|
+
}
|
|
2859
|
+
return {
|
|
2860
|
+
resolve(sessionID, query) {
|
|
2861
|
+
if (override) return Promise.resolve(override);
|
|
2862
|
+
if (!options.fetch) return Promise.resolve(void 0);
|
|
2863
|
+
let perSession = cache.get(sessionID);
|
|
2864
|
+
if (!perSession) {
|
|
2865
|
+
perSession = /* @__PURE__ */ new Map();
|
|
2866
|
+
cache.set(sessionID, perSession);
|
|
2867
|
+
}
|
|
2868
|
+
const key = `${query.provider}\0${query.model}`;
|
|
2869
|
+
let pending = perSession.get(key);
|
|
2870
|
+
if (!pending) {
|
|
2871
|
+
pending = lookup(query).catch(() => void 0);
|
|
2872
|
+
perSession.set(key, pending);
|
|
2873
|
+
}
|
|
2874
|
+
return pending;
|
|
2875
|
+
},
|
|
2876
|
+
forget(sessionID) {
|
|
2877
|
+
cache.delete(sessionID);
|
|
2878
|
+
}
|
|
2879
|
+
};
|
|
2880
|
+
}
|
|
2881
|
+
function promptToolsAttributes(resolved) {
|
|
2882
|
+
if (!resolved) return [];
|
|
2883
|
+
return [
|
|
2884
|
+
promptToolsAttribute(resolved.tools),
|
|
2885
|
+
resolved.source !== void 0 ? attrString(PROMPT_TOOLS_SOURCE_ATTRIBUTE, resolved.source) : void 0
|
|
2886
|
+
];
|
|
2887
|
+
}
|
|
2888
|
+
|
|
2649
2889
|
// src/bounded.ts
|
|
2650
2890
|
var TRUNCATION_MARKER2 = "...[truncated by raindrop]";
|
|
2651
2891
|
var MAX_TEXT_FIELD_CHARS = 1e6;
|
|
@@ -2782,6 +3022,8 @@ export {
|
|
|
2782
3022
|
trackSelfDiagnosticsSignal,
|
|
2783
3023
|
EventShipper3 as EventShipper,
|
|
2784
3024
|
TraceShipper3 as TraceShipper,
|
|
3025
|
+
createToolCatalog,
|
|
3026
|
+
promptToolsAttributes,
|
|
2785
3027
|
capText2 as capText,
|
|
2786
3028
|
boundedStringify,
|
|
2787
3029
|
buildLlmGenAiAttributes
|