@raindrop-ai/opencode-plugin 0.2.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 +94 -0
- package/dist/{chunk-4DAI6CYK.js → chunk-ZG47FVK7.js} +460 -3
- package/dist/index.cjs +534 -28
- package/dist/index.d.cts +12 -2
- package/dist/index.d.ts +12 -2
- package/dist/index.js +107 -27
- package/dist/{index.d-vgBcEZbX.d.cts → self-diagnostics-CLW6h4zB.d.cts} +60 -1
- package/dist/{index.d-vgBcEZbX.d.ts → self-diagnostics-CLW6h4zB.d.ts} +60 -1
- package/dist/v2.cjs +527 -14
- package/dist/v2.d.cts +10 -2
- package/dist/v2.d.ts +10 -2
- package/dist/v2.js +81 -13
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
import { I as IdentifyInput, A as AppGitOptions } from './
|
|
1
|
+
import { I as IdentifyInput, A as AppGitOptions, S as SelfDiagnosticsOptions, P as PromptToolsOverride } from './self-diagnostics-CLW6h4zB.cjs';
|
|
2
|
+
export { a as SelfDiagnosticsSignalDefinition, b as SelfDiagnosticsSignalDefinitions } from './self-diagnostics-CLW6h4zB.cjs';
|
|
2
3
|
import { Hooks, PluginInput } from '@opencode-ai/plugin';
|
|
3
4
|
|
|
4
5
|
interface RaindropOpencodeOptions {
|
|
5
6
|
/** Application Git identity override. false disables enrichment. */
|
|
6
7
|
appGit?: AppGitOptions | false;
|
|
8
|
+
/** Built-in self-diagnostics: injects a `__raindrop_report` tool when enabled. */
|
|
9
|
+
selfDiagnostics?: SelfDiagnosticsOptions;
|
|
10
|
+
/**
|
|
11
|
+
* Overrides the tool catalog recorded as `ai.prompt.tools` on every model
|
|
12
|
+
* span; skips the OpenCode `client.tool.list` lookup entirely.
|
|
13
|
+
*/
|
|
14
|
+
tools?: PromptToolsOverride;
|
|
7
15
|
}
|
|
8
16
|
/**
|
|
9
17
|
* The Raindrop control handle exposed alongside the OpenCode hooks.
|
|
@@ -25,6 +33,8 @@ interface RaindropOpencodeHandle {
|
|
|
25
33
|
*/
|
|
26
34
|
identify(users: IdentifyInput | IdentifyInput[]): Promise<void>;
|
|
27
35
|
};
|
|
36
|
+
/** Raindrop eventId of the turn currently open for this OpenCode session, if any. */
|
|
37
|
+
currentEventId(sessionID: string): string | undefined;
|
|
28
38
|
/** Drain the buffered event + trace shippers. */
|
|
29
39
|
flush(): Promise<void>;
|
|
30
40
|
/** Flush and tear down the shippers (also wired into session teardown). */
|
|
@@ -53,4 +63,4 @@ type RaindropOpencodeHooks = Hooks & {
|
|
|
53
63
|
*/
|
|
54
64
|
declare function plugin(input: PluginInput, opts?: RaindropOpencodeOptions): Promise<RaindropOpencodeHooks>;
|
|
55
65
|
|
|
56
|
-
export { IdentifyInput, type RaindropOpencodeHandle, type RaindropOpencodeHooks, type RaindropOpencodeOptions, plugin as default };
|
|
66
|
+
export { IdentifyInput, type RaindropOpencodeHandle, type RaindropOpencodeHooks, type RaindropOpencodeOptions, SelfDiagnosticsOptions, plugin as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
import { I as IdentifyInput, A as AppGitOptions } from './
|
|
1
|
+
import { I as IdentifyInput, A as AppGitOptions, S as SelfDiagnosticsOptions, P as PromptToolsOverride } from './self-diagnostics-CLW6h4zB.js';
|
|
2
|
+
export { a as SelfDiagnosticsSignalDefinition, b as SelfDiagnosticsSignalDefinitions } from './self-diagnostics-CLW6h4zB.js';
|
|
2
3
|
import { Hooks, PluginInput } from '@opencode-ai/plugin';
|
|
3
4
|
|
|
4
5
|
interface RaindropOpencodeOptions {
|
|
5
6
|
/** Application Git identity override. false disables enrichment. */
|
|
6
7
|
appGit?: AppGitOptions | false;
|
|
8
|
+
/** Built-in self-diagnostics: injects a `__raindrop_report` tool when enabled. */
|
|
9
|
+
selfDiagnostics?: SelfDiagnosticsOptions;
|
|
10
|
+
/**
|
|
11
|
+
* Overrides the tool catalog recorded as `ai.prompt.tools` on every model
|
|
12
|
+
* span; skips the OpenCode `client.tool.list` lookup entirely.
|
|
13
|
+
*/
|
|
14
|
+
tools?: PromptToolsOverride;
|
|
7
15
|
}
|
|
8
16
|
/**
|
|
9
17
|
* The Raindrop control handle exposed alongside the OpenCode hooks.
|
|
@@ -25,6 +33,8 @@ interface RaindropOpencodeHandle {
|
|
|
25
33
|
*/
|
|
26
34
|
identify(users: IdentifyInput | IdentifyInput[]): Promise<void>;
|
|
27
35
|
};
|
|
36
|
+
/** Raindrop eventId of the turn currently open for this OpenCode session, if any. */
|
|
37
|
+
currentEventId(sessionID: string): string | undefined;
|
|
28
38
|
/** Drain the buffered event + trace shippers. */
|
|
29
39
|
flush(): Promise<void>;
|
|
30
40
|
/** Flush and tear down the shippers (also wired into session teardown). */
|
|
@@ -53,4 +63,4 @@ type RaindropOpencodeHooks = Hooks & {
|
|
|
53
63
|
*/
|
|
54
64
|
declare function plugin(input: PluginInput, opts?: RaindropOpencodeOptions): Promise<RaindropOpencodeHooks>;
|
|
55
65
|
|
|
56
|
-
export { IdentifyInput, type RaindropOpencodeHandle, type RaindropOpencodeHooks, type RaindropOpencodeOptions, plugin as default };
|
|
66
|
+
export { IdentifyInput, type RaindropOpencodeHandle, type RaindropOpencodeHooks, type RaindropOpencodeOptions, SelfDiagnosticsOptions, plugin as default };
|
package/dist/index.js
CHANGED
|
@@ -2,17 +2,25 @@ import {
|
|
|
2
2
|
EventShipper,
|
|
3
3
|
PLUGIN_NAME,
|
|
4
4
|
PLUGIN_VERSION,
|
|
5
|
+
SELF_DIAGNOSTICS_ACK,
|
|
5
6
|
TraceShipper,
|
|
6
7
|
attrString,
|
|
7
8
|
boundedStringify,
|
|
8
9
|
buildLlmGenAiAttributes,
|
|
9
10
|
capText,
|
|
10
11
|
createAppGitContext,
|
|
12
|
+
createToolCatalog,
|
|
11
13
|
generateId,
|
|
12
14
|
loadConfig,
|
|
15
|
+
normalizeSelfDiagnosticsConfig,
|
|
13
16
|
nowUnixNanoString,
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
promptToolsAttributes,
|
|
18
|
+
resolveLocalDebuggerBaseUrl,
|
|
19
|
+
trackSelfDiagnosticsSignal
|
|
20
|
+
} from "./chunk-ZG47FVK7.js";
|
|
21
|
+
|
|
22
|
+
// src/index.ts
|
|
23
|
+
import { tool } from "@opencode-ai/plugin";
|
|
16
24
|
|
|
17
25
|
// src/tracing.ts
|
|
18
26
|
import { hostname as osHostname } from "os";
|
|
@@ -129,7 +137,7 @@ function markTaskCallFinished(sessionID, callID) {
|
|
|
129
137
|
running.delete(callID);
|
|
130
138
|
if (running.size === 0) runningTaskCallsBySession.delete(sessionID);
|
|
131
139
|
}
|
|
132
|
-
function endPendingToolSpanWithError(state, callID,
|
|
140
|
+
function endPendingToolSpanWithError(state, callID, tool2, toolCallArgs, errorMessage, traceShipper) {
|
|
133
141
|
const startInfo = state.toolSpanStarts.get(callID);
|
|
134
142
|
if (!startInfo) return false;
|
|
135
143
|
state.toolSpanStarts.delete(callID);
|
|
@@ -151,7 +159,7 @@ function endPendingToolSpanWithError(state, callID, tool, toolCallArgs, errorMes
|
|
|
151
159
|
startTimeUnixNano: startInfo.startTimeUnixNano,
|
|
152
160
|
attributes: [
|
|
153
161
|
attrString("ai.operationId", "ai.toolCall"),
|
|
154
|
-
attrString("ai.toolCall.name",
|
|
162
|
+
attrString("ai.toolCall.name", tool2),
|
|
155
163
|
attrString("ai.toolCall.id", callID)
|
|
156
164
|
]
|
|
157
165
|
});
|
|
@@ -188,7 +196,7 @@ function getHostname() {
|
|
|
188
196
|
return h;
|
|
189
197
|
}
|
|
190
198
|
}
|
|
191
|
-
function
|
|
199
|
+
function createTracing(config, worktree, directory, eventShipper, traceShipper, toolCatalog) {
|
|
192
200
|
function log(msg, data) {
|
|
193
201
|
if (!config.debug) return;
|
|
194
202
|
const prefix = `[raindrop-ai/opencode-plugin] [info] ${msg}`;
|
|
@@ -214,7 +222,15 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
214
222
|
callKey,
|
|
215
223
|
log
|
|
216
224
|
});
|
|
217
|
-
|
|
225
|
+
const hooks = {
|
|
226
|
+
// Fires before each model call with the model already resolved: start the
|
|
227
|
+
// catalog lookup now so the span attributes rarely wait on it later.
|
|
228
|
+
"chat.params": async (input) => {
|
|
229
|
+
void (toolCatalog == null ? void 0 : toolCatalog.resolve(input.sessionID, {
|
|
230
|
+
provider: input.model.providerID,
|
|
231
|
+
model: input.model.id
|
|
232
|
+
}));
|
|
233
|
+
},
|
|
218
234
|
// ------------------------------------------------------------------
|
|
219
235
|
// event — session lifecycle + streaming parts
|
|
220
236
|
// ------------------------------------------------------------------
|
|
@@ -259,14 +275,14 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
259
275
|
if (partObj["type"] === "text" && typeof partObj["text"] === "string") {
|
|
260
276
|
state.outputParts.set(messageId, capText(partObj["text"]));
|
|
261
277
|
} else if (partObj["type"] === "tool" && messageId) {
|
|
262
|
-
const
|
|
278
|
+
const tool2 = partObj["tool"];
|
|
263
279
|
const callID = partObj["callID"];
|
|
264
280
|
const partState = partObj["state"];
|
|
265
281
|
if (callID == null || callID === "")
|
|
266
282
|
throw new Error("message.part.updated: part.callID is required for tool part");
|
|
267
283
|
if (partState == null || typeof partState !== "object")
|
|
268
284
|
throw new Error("message.part.updated: part.state is required for tool part");
|
|
269
|
-
if (
|
|
285
|
+
if (tool2 === "task") {
|
|
270
286
|
const metadata = partState["metadata"];
|
|
271
287
|
const childSessionId = metadata != null && typeof metadata === "object" ? metadata["sessionId"] : void 0;
|
|
272
288
|
if (childSessionId != null && childSessionId !== "") {
|
|
@@ -291,11 +307,11 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
291
307
|
if (endPendingToolSpanWithError(
|
|
292
308
|
state,
|
|
293
309
|
callID,
|
|
294
|
-
|
|
310
|
+
tool2,
|
|
295
311
|
toolCallArgs,
|
|
296
312
|
errorMessage,
|
|
297
313
|
traceShipper
|
|
298
|
-
) &&
|
|
314
|
+
) && tool2 === "task") {
|
|
299
315
|
markTaskCallFinished(partSessionID, callID);
|
|
300
316
|
}
|
|
301
317
|
}
|
|
@@ -339,6 +355,9 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
339
355
|
"message.updated: providerID and modelID are required non-empty strings"
|
|
340
356
|
);
|
|
341
357
|
const modelName = `${providerID}/${modelID}`;
|
|
358
|
+
const promptTools = promptToolsAttributes(
|
|
359
|
+
await (toolCatalog == null ? void 0 : toolCatalog.resolve(String(msgSessionID), { provider: providerID, model: modelID }))
|
|
360
|
+
);
|
|
342
361
|
const finishReason = info2["finish"];
|
|
343
362
|
const outputText = state.outputParts.get(messageId);
|
|
344
363
|
const reasoningText = state.reasoningParts.get(messageId);
|
|
@@ -364,7 +383,8 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
364
383
|
const llmAttrs = [
|
|
365
384
|
attrString("ai.operationId", "generateText"),
|
|
366
385
|
attrString("ai.response.text", responseText),
|
|
367
|
-
...buildLlmGenAiAttributes({ providerID, modelID, tokens: tokensObj })
|
|
386
|
+
...buildLlmGenAiAttributes({ providerID, modelID, tokens: tokensObj }),
|
|
387
|
+
...promptTools
|
|
368
388
|
];
|
|
369
389
|
if (state.currentSystemPrompt) {
|
|
370
390
|
llmAttrs.push(
|
|
@@ -400,7 +420,8 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
400
420
|
buildPromptMessages(state.currentSystemPrompt, state.currentInput)
|
|
401
421
|
),
|
|
402
422
|
attrString("ai.response.text", turnOutputText),
|
|
403
|
-
...buildLlmGenAiAttributes({ providerID, modelID, tokens: tokensObj })
|
|
423
|
+
...buildLlmGenAiAttributes({ providerID, modelID, tokens: tokensObj }),
|
|
424
|
+
...promptTools
|
|
404
425
|
];
|
|
405
426
|
if (state.currentSystemPrompt) {
|
|
406
427
|
llmAttrs.push(
|
|
@@ -445,7 +466,8 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
445
466
|
buildPromptMessages(state.currentSystemPrompt, state.currentInput)
|
|
446
467
|
),
|
|
447
468
|
attrString("ai.response.text", turnOutputText),
|
|
448
|
-
...buildLlmGenAiAttributes({ providerID, modelID, tokens: tokensObj })
|
|
469
|
+
...buildLlmGenAiAttributes({ providerID, modelID, tokens: tokensObj }),
|
|
470
|
+
...promptTools
|
|
449
471
|
];
|
|
450
472
|
if (isCompaction) {
|
|
451
473
|
rootAttrs.push(attrString("is_compaction", "true"));
|
|
@@ -511,6 +533,7 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
511
533
|
if (state.parentId) {
|
|
512
534
|
cleanupSessionParentMap(String(sessionID));
|
|
513
535
|
sessions.delete(String(sessionID));
|
|
536
|
+
toolCatalog == null ? void 0 : toolCatalog.forget(String(sessionID));
|
|
514
537
|
} else {
|
|
515
538
|
}
|
|
516
539
|
} else if (event.type === "session.deleted") {
|
|
@@ -527,6 +550,7 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
527
550
|
cleanupSessionParentMap(String(sessionID));
|
|
528
551
|
await Promise.all([eventShipper.flush(), traceShipper.flush()]);
|
|
529
552
|
sessions.delete(String(sessionID));
|
|
553
|
+
toolCatalog == null ? void 0 : toolCatalog.forget(String(sessionID));
|
|
530
554
|
} else if (event.type === "session.error") {
|
|
531
555
|
const errorSessionID = (_h = props["sessionID"]) != null ? _h : sessionID;
|
|
532
556
|
if (errorSessionID === void 0 || errorSessionID === "")
|
|
@@ -552,6 +576,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
552
576
|
cleanupSessionParentMap(String(errorSessionID));
|
|
553
577
|
await Promise.all([eventShipper.flush(), traceShipper.flush()]);
|
|
554
578
|
sessions.delete(String(errorSessionID));
|
|
579
|
+
toolCatalog == null ? void 0 : toolCatalog.forget(String(errorSessionID));
|
|
555
580
|
}
|
|
556
581
|
} catch (err) {
|
|
557
582
|
rateLimitedErrorLog(
|
|
@@ -672,20 +697,20 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
672
697
|
"tool.execute.before": async (toolInput, _output) => {
|
|
673
698
|
var _a, _b, _c;
|
|
674
699
|
try {
|
|
675
|
-
const { tool, sessionID, callID } = toolInput;
|
|
700
|
+
const { tool: tool2, sessionID, callID } = toolInput;
|
|
676
701
|
const state = sessions.get(sessionID);
|
|
677
702
|
if (!state || !state.currentEventId) return;
|
|
678
703
|
const spanParent = state.parentId && state.parentTaskSpanIds ? state.parentTaskSpanIds : (_a = state.currentRootSpan) == null ? void 0 : _a.ids;
|
|
679
704
|
if (!spanParent) return;
|
|
680
705
|
const startTimeUnixNano = nowUnixNanoString();
|
|
681
|
-
if (
|
|
706
|
+
if (tool2 === "task") {
|
|
682
707
|
const liveTaskSpan = traceShipper.startSpan({
|
|
683
708
|
name: "ai.toolCall",
|
|
684
709
|
parent: spanParent,
|
|
685
710
|
eventId: state.currentEventId,
|
|
686
711
|
attributes: [
|
|
687
712
|
attrString("ai.operationId", "ai.toolCall"),
|
|
688
|
-
attrString("ai.toolCall.name",
|
|
713
|
+
attrString("ai.toolCall.name", tool2),
|
|
689
714
|
attrString("ai.toolCall.id", callID)
|
|
690
715
|
]
|
|
691
716
|
});
|
|
@@ -710,7 +735,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
710
735
|
startTimeUnixNano,
|
|
711
736
|
parent: spanParent,
|
|
712
737
|
eventId: state.currentEventId,
|
|
713
|
-
name:
|
|
738
|
+
name: tool2,
|
|
714
739
|
liveSpan: liveTaskSpan
|
|
715
740
|
});
|
|
716
741
|
} else {
|
|
@@ -718,7 +743,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
718
743
|
startTimeUnixNano,
|
|
719
744
|
parent: spanParent,
|
|
720
745
|
eventId: state.currentEventId,
|
|
721
|
-
name:
|
|
746
|
+
name: tool2
|
|
722
747
|
});
|
|
723
748
|
}
|
|
724
749
|
} catch (err) {
|
|
@@ -733,7 +758,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
733
758
|
// ------------------------------------------------------------------
|
|
734
759
|
"tool.execute.after": async (toolInput, result) => {
|
|
735
760
|
try {
|
|
736
|
-
const { tool, sessionID, callID, args } = toolInput;
|
|
761
|
+
const { tool: tool2, sessionID, callID, args } = toolInput;
|
|
737
762
|
const state = sessions.get(sessionID);
|
|
738
763
|
if (!state || !state.currentEventId) return;
|
|
739
764
|
if (args === void 0 || args === null)
|
|
@@ -743,7 +768,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
743
768
|
state.toolSpanStarts.delete(callID);
|
|
744
769
|
const resultMetadata = result.metadata;
|
|
745
770
|
const childSessionId = resultMetadata == null ? void 0 : resultMetadata["sessionId"];
|
|
746
|
-
if (
|
|
771
|
+
if (tool2 === "task" && childSessionId) {
|
|
747
772
|
mapChildSessionToParent.set(childSessionId, { parentId: sessionID });
|
|
748
773
|
attachChildSessionToParentTask(childSessionId, sessionID, callID, "tool.execute.after");
|
|
749
774
|
}
|
|
@@ -768,7 +793,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
768
793
|
endTimeUnixNano,
|
|
769
794
|
attributes: [
|
|
770
795
|
attrString("ai.operationId", "ai.toolCall"),
|
|
771
|
-
attrString("ai.toolCall.name",
|
|
796
|
+
attrString("ai.toolCall.name", tool2),
|
|
772
797
|
attrString("ai.toolCall.id", callID),
|
|
773
798
|
attrString("ai.toolCall.args", toolCallArgs),
|
|
774
799
|
attrString("ai.toolCall.result", toolResult)
|
|
@@ -776,7 +801,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
776
801
|
});
|
|
777
802
|
}
|
|
778
803
|
}
|
|
779
|
-
if (
|
|
804
|
+
if (tool2 === "task") {
|
|
780
805
|
markTaskCallFinished(sessionID, callID);
|
|
781
806
|
}
|
|
782
807
|
} catch (err) {
|
|
@@ -829,16 +854,24 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
829
854
|
}
|
|
830
855
|
}
|
|
831
856
|
};
|
|
857
|
+
return {
|
|
858
|
+
hooks,
|
|
859
|
+
currentEventId(sessionID) {
|
|
860
|
+
var _a;
|
|
861
|
+
return (_a = sessions.get(sessionID)) == null ? void 0 : _a.currentEventId;
|
|
862
|
+
}
|
|
863
|
+
};
|
|
832
864
|
}
|
|
833
865
|
|
|
834
866
|
// src/index.ts
|
|
835
|
-
function createRaindropHandle(eventShipper, traceShipper, appGitContext) {
|
|
867
|
+
function createRaindropHandle(eventShipper, traceShipper, appGitContext, currentEventId) {
|
|
836
868
|
return {
|
|
837
869
|
users: {
|
|
838
870
|
async identify(users) {
|
|
839
871
|
await eventShipper.identify(users);
|
|
840
872
|
}
|
|
841
873
|
},
|
|
874
|
+
currentEventId,
|
|
842
875
|
async flush() {
|
|
843
876
|
await Promise.all([eventShipper.flush(), traceShipper.flush()]);
|
|
844
877
|
},
|
|
@@ -855,7 +888,7 @@ function createRaindropHandle(eventShipper, traceShipper, appGitContext) {
|
|
|
855
888
|
};
|
|
856
889
|
}
|
|
857
890
|
async function plugin(input, opts = {}) {
|
|
858
|
-
var _a, _b, _c;
|
|
891
|
+
var _a, _b, _c, _d, _e;
|
|
859
892
|
const config = loadConfig(input.directory);
|
|
860
893
|
function appLog(level, message) {
|
|
861
894
|
console.log(`[raindrop-ai/opencode-plugin] [${level}] ${message}`);
|
|
@@ -899,14 +932,61 @@ async function plugin(input, opts = {}) {
|
|
|
899
932
|
appGitContext
|
|
900
933
|
});
|
|
901
934
|
const worktree = (_c = input.worktree) != null ? _c : input.directory;
|
|
902
|
-
const
|
|
935
|
+
const toolCatalog = createToolCatalog({
|
|
936
|
+
override: (_d = opts.tools) != null ? _d : config.tools,
|
|
937
|
+
fetch: (query) => input.client.tool.list({ query }),
|
|
938
|
+
debug: config.debug
|
|
939
|
+
});
|
|
940
|
+
const tracing = createTracing(
|
|
903
941
|
config,
|
|
904
942
|
worktree,
|
|
905
943
|
input.directory,
|
|
906
944
|
eventShipper,
|
|
907
|
-
traceShipper
|
|
945
|
+
traceShipper,
|
|
946
|
+
toolCatalog
|
|
947
|
+
);
|
|
948
|
+
const hooks = tracing.hooks;
|
|
949
|
+
const selfDiagnostics = normalizeSelfDiagnosticsConfig(
|
|
950
|
+
(_e = opts.selfDiagnostics) != null ? _e : config.selfDiagnostics
|
|
908
951
|
);
|
|
909
|
-
|
|
952
|
+
if (selfDiagnostics && !config.writeKey.trim()) {
|
|
953
|
+
appLog(
|
|
954
|
+
"warn",
|
|
955
|
+
`selfDiagnostics enabled but RAINDROP_WRITE_KEY is not set \u2014 the ${selfDiagnostics.toolName} tool is not registered (signals require the cloud destination).`
|
|
956
|
+
);
|
|
957
|
+
}
|
|
958
|
+
const [firstSignalKey, ...restSignalKeys] = config.writeKey.trim() && selfDiagnostics ? selfDiagnostics.signalKeys : [];
|
|
959
|
+
if (selfDiagnostics && firstSignalKey !== void 0) {
|
|
960
|
+
const cfg = selfDiagnostics;
|
|
961
|
+
hooks.tool = {
|
|
962
|
+
[cfg.toolName]: tool({
|
|
963
|
+
description: cfg.toolDescription,
|
|
964
|
+
args: {
|
|
965
|
+
category: tool.schema.enum([firstSignalKey, ...restSignalKeys]),
|
|
966
|
+
detail: tool.schema.string()
|
|
967
|
+
},
|
|
968
|
+
async execute(args, ctx) {
|
|
969
|
+
await trackSelfDiagnosticsSignal(
|
|
970
|
+
args,
|
|
971
|
+
cfg,
|
|
972
|
+
eventShipper,
|
|
973
|
+
tracing.currentEventId(ctx.sessionID),
|
|
974
|
+
config.debug
|
|
975
|
+
);
|
|
976
|
+
return SELF_DIAGNOSTICS_ACK;
|
|
977
|
+
}
|
|
978
|
+
})
|
|
979
|
+
};
|
|
980
|
+
}
|
|
981
|
+
return {
|
|
982
|
+
...hooks,
|
|
983
|
+
raindrop: createRaindropHandle(
|
|
984
|
+
eventShipper,
|
|
985
|
+
traceShipper,
|
|
986
|
+
appGitContext,
|
|
987
|
+
tracing.currentEventId
|
|
988
|
+
)
|
|
989
|
+
};
|
|
910
990
|
}
|
|
911
991
|
export {
|
|
912
992
|
plugin as default
|
|
@@ -85,5 +85,64 @@ declare global {
|
|
|
85
85
|
var RAINDROP_CONTEXT_MANAGER: (new () => ContextManager) | undefined;
|
|
86
86
|
var RAINDROP_ASYNC_LOCAL_STORAGE: (new <T>() => AsyncLocalStorageLike<T>) | undefined;
|
|
87
87
|
}
|
|
88
|
+
type JsonSchema = Record<string, unknown>;
|
|
89
|
+
type FunctionToolDeclaration = {
|
|
90
|
+
type: "function";
|
|
91
|
+
name: string;
|
|
92
|
+
description?: string;
|
|
93
|
+
inputSchema?: JsonSchema;
|
|
94
|
+
};
|
|
95
|
+
type ProviderDefinedToolDeclaration = {
|
|
96
|
+
type: "provider-defined";
|
|
97
|
+
id?: string;
|
|
98
|
+
name: string;
|
|
99
|
+
args?: Record<string, unknown>;
|
|
100
|
+
};
|
|
101
|
+
type ToolDeclaration = FunctionToolDeclaration | ProviderDefinedToolDeclaration;
|
|
102
|
+
/**
|
|
103
|
+
* What callers hand to a `tools` override. The canonical `ToolDeclaration`
|
|
104
|
+
* shape is accepted as-is; so is any framework shape `normalizeToolDeclarations`
|
|
105
|
+
* recognizes (OpenAI, Anthropic, Bedrock, LangChain, Pi, Mastra, AI SDK).
|
|
106
|
+
*/
|
|
107
|
+
type ToolDeclarationInput = ToolDeclaration | {
|
|
108
|
+
name: string;
|
|
109
|
+
description?: string;
|
|
110
|
+
inputSchema?: JsonSchema;
|
|
111
|
+
parameters?: JsonSchema;
|
|
112
|
+
};
|
|
113
|
+
type PromptToolsOverride = ReadonlyArray<ToolDeclarationInput | unknown>;
|
|
114
|
+
|
|
115
|
+
type SelfDiagnosticsSignalDefinition = {
|
|
116
|
+
/**
|
|
117
|
+
* Human-readable meaning of this signal.
|
|
118
|
+
* Used in the injected tool schema and stored in signal properties.
|
|
119
|
+
*/
|
|
120
|
+
description: string;
|
|
121
|
+
/**
|
|
122
|
+
* Optional default sentiment for this signal key.
|
|
123
|
+
* This can help dashboards classify negative/positive programmatic signals.
|
|
124
|
+
*/
|
|
125
|
+
sentiment?: "POSITIVE" | "NEGATIVE";
|
|
126
|
+
};
|
|
127
|
+
type SelfDiagnosticsSignalDefinitions = Record<string, SelfDiagnosticsSignalDefinition>;
|
|
128
|
+
type SelfDiagnosticsOptions = {
|
|
129
|
+
/** Enable automatic injection of the self diagnostics tool. Default: false */
|
|
130
|
+
enabled?: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Signal keys and descriptions exposed to the model.
|
|
133
|
+
* Defaults to a built-in set when omitted.
|
|
134
|
+
*/
|
|
135
|
+
signals?: SelfDiagnosticsSignalDefinitions;
|
|
136
|
+
/**
|
|
137
|
+
* Optional extra guidance for when the model should emit self diagnostics.
|
|
138
|
+
* The SDK still generates a full tool prompt from `signals`.
|
|
139
|
+
*/
|
|
140
|
+
guidance?: string;
|
|
141
|
+
/**
|
|
142
|
+
* Optional tool name override for the injected self diagnostics tool.
|
|
143
|
+
* Defaults to "__raindrop_report".
|
|
144
|
+
*/
|
|
145
|
+
toolName?: string;
|
|
146
|
+
};
|
|
88
147
|
|
|
89
|
-
export type { AppGitOptions as A, IdentifyInput as I,
|
|
148
|
+
export type { AppGitOptions as A, IdentifyInput as I, PromptToolsOverride as P, SelfDiagnosticsOptions as S, SelfDiagnosticsSignalDefinition as a, SelfDiagnosticsSignalDefinitions as b, SignalInput as c };
|
|
@@ -85,5 +85,64 @@ declare global {
|
|
|
85
85
|
var RAINDROP_CONTEXT_MANAGER: (new () => ContextManager) | undefined;
|
|
86
86
|
var RAINDROP_ASYNC_LOCAL_STORAGE: (new <T>() => AsyncLocalStorageLike<T>) | undefined;
|
|
87
87
|
}
|
|
88
|
+
type JsonSchema = Record<string, unknown>;
|
|
89
|
+
type FunctionToolDeclaration = {
|
|
90
|
+
type: "function";
|
|
91
|
+
name: string;
|
|
92
|
+
description?: string;
|
|
93
|
+
inputSchema?: JsonSchema;
|
|
94
|
+
};
|
|
95
|
+
type ProviderDefinedToolDeclaration = {
|
|
96
|
+
type: "provider-defined";
|
|
97
|
+
id?: string;
|
|
98
|
+
name: string;
|
|
99
|
+
args?: Record<string, unknown>;
|
|
100
|
+
};
|
|
101
|
+
type ToolDeclaration = FunctionToolDeclaration | ProviderDefinedToolDeclaration;
|
|
102
|
+
/**
|
|
103
|
+
* What callers hand to a `tools` override. The canonical `ToolDeclaration`
|
|
104
|
+
* shape is accepted as-is; so is any framework shape `normalizeToolDeclarations`
|
|
105
|
+
* recognizes (OpenAI, Anthropic, Bedrock, LangChain, Pi, Mastra, AI SDK).
|
|
106
|
+
*/
|
|
107
|
+
type ToolDeclarationInput = ToolDeclaration | {
|
|
108
|
+
name: string;
|
|
109
|
+
description?: string;
|
|
110
|
+
inputSchema?: JsonSchema;
|
|
111
|
+
parameters?: JsonSchema;
|
|
112
|
+
};
|
|
113
|
+
type PromptToolsOverride = ReadonlyArray<ToolDeclarationInput | unknown>;
|
|
114
|
+
|
|
115
|
+
type SelfDiagnosticsSignalDefinition = {
|
|
116
|
+
/**
|
|
117
|
+
* Human-readable meaning of this signal.
|
|
118
|
+
* Used in the injected tool schema and stored in signal properties.
|
|
119
|
+
*/
|
|
120
|
+
description: string;
|
|
121
|
+
/**
|
|
122
|
+
* Optional default sentiment for this signal key.
|
|
123
|
+
* This can help dashboards classify negative/positive programmatic signals.
|
|
124
|
+
*/
|
|
125
|
+
sentiment?: "POSITIVE" | "NEGATIVE";
|
|
126
|
+
};
|
|
127
|
+
type SelfDiagnosticsSignalDefinitions = Record<string, SelfDiagnosticsSignalDefinition>;
|
|
128
|
+
type SelfDiagnosticsOptions = {
|
|
129
|
+
/** Enable automatic injection of the self diagnostics tool. Default: false */
|
|
130
|
+
enabled?: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Signal keys and descriptions exposed to the model.
|
|
133
|
+
* Defaults to a built-in set when omitted.
|
|
134
|
+
*/
|
|
135
|
+
signals?: SelfDiagnosticsSignalDefinitions;
|
|
136
|
+
/**
|
|
137
|
+
* Optional extra guidance for when the model should emit self diagnostics.
|
|
138
|
+
* The SDK still generates a full tool prompt from `signals`.
|
|
139
|
+
*/
|
|
140
|
+
guidance?: string;
|
|
141
|
+
/**
|
|
142
|
+
* Optional tool name override for the injected self diagnostics tool.
|
|
143
|
+
* Defaults to "__raindrop_report".
|
|
144
|
+
*/
|
|
145
|
+
toolName?: string;
|
|
146
|
+
};
|
|
88
147
|
|
|
89
|
-
export type { AppGitOptions as A, IdentifyInput as I,
|
|
148
|
+
export type { AppGitOptions as A, IdentifyInput as I, PromptToolsOverride as P, SelfDiagnosticsOptions as S, SelfDiagnosticsSignalDefinition as a, SelfDiagnosticsSignalDefinitions as b, SignalInput as c };
|