@raindrop-ai/opencode-plugin 0.0.5 → 0.0.6
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/dist/index.cjs +109 -90
- package/dist/index.js +109 -90
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -45,14 +45,91 @@ function loadConfig(projectDirectory) {
|
|
|
45
45
|
} catch (e) {
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
+
let eventMetadata;
|
|
49
|
+
const envMeta = process.env["RAINDROP_EVENT_METADATA"];
|
|
50
|
+
if (envMeta) {
|
|
51
|
+
try {
|
|
52
|
+
eventMetadata = JSON.parse(envMeta);
|
|
53
|
+
} catch (e) {
|
|
54
|
+
}
|
|
55
|
+
}
|
|
48
56
|
return {
|
|
49
57
|
writeKey: (_b = (_a = process.env["RAINDROP_WRITE_KEY"]) != null ? _a : merged.write_key) != null ? _b : "",
|
|
50
58
|
endpoint: (_d = (_c = process.env["RAINDROP_API_URL"]) != null ? _c : merged.api_url) != null ? _d : "https://api.raindrop.ai/v1",
|
|
51
59
|
eventName: (_e = merged.event_name) != null ? _e : "opencode_session",
|
|
52
|
-
debug: process.env["RAINDROP_DEBUG"] === "true" ? true : (_f = merged.debug) != null ? _f : false
|
|
60
|
+
debug: process.env["RAINDROP_DEBUG"] === "true" ? true : (_f = merged.debug) != null ? _f : false,
|
|
61
|
+
eventMetadata
|
|
53
62
|
};
|
|
54
63
|
}
|
|
55
64
|
|
|
65
|
+
// package.json
|
|
66
|
+
var package_default = {
|
|
67
|
+
name: "@raindrop-ai/opencode-plugin",
|
|
68
|
+
version: "0.0.6",
|
|
69
|
+
description: "Raindrop observability plugin for OpenCode \u2014 automatic session/event/span tracing",
|
|
70
|
+
type: "module",
|
|
71
|
+
main: "dist/index.cjs",
|
|
72
|
+
module: "dist/index.js",
|
|
73
|
+
types: "dist/index.d.ts",
|
|
74
|
+
exports: {
|
|
75
|
+
".": {
|
|
76
|
+
types: "./dist/index.d.ts",
|
|
77
|
+
import: "./dist/index.js",
|
|
78
|
+
require: "./dist/index.cjs"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
sideEffects: false,
|
|
82
|
+
files: [
|
|
83
|
+
"dist/**"
|
|
84
|
+
],
|
|
85
|
+
scripts: {
|
|
86
|
+
build: "tsup",
|
|
87
|
+
dev: "tsup --watch",
|
|
88
|
+
clean: "rm -rf dist",
|
|
89
|
+
test: "cd tests && pnpm test"
|
|
90
|
+
},
|
|
91
|
+
peerDependencies: {
|
|
92
|
+
"@opencode-ai/plugin": ">=1.2.0",
|
|
93
|
+
"@opencode-ai/sdk": ">=1.2.0"
|
|
94
|
+
},
|
|
95
|
+
peerDependenciesMeta: {
|
|
96
|
+
"@opencode-ai/sdk": {
|
|
97
|
+
optional: true
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
devDependencies: {
|
|
101
|
+
"@raindrop-ai/core": "workspace:*",
|
|
102
|
+
"@opencode-ai/plugin": "^1.2.0",
|
|
103
|
+
"@opencode-ai/sdk": "^1.2.0",
|
|
104
|
+
"@types/node": "^20.11.17",
|
|
105
|
+
tsup: "^8.4.0",
|
|
106
|
+
typescript: "^5.3.3"
|
|
107
|
+
},
|
|
108
|
+
tsup: {
|
|
109
|
+
entry: [
|
|
110
|
+
"src/index.ts"
|
|
111
|
+
],
|
|
112
|
+
format: [
|
|
113
|
+
"cjs",
|
|
114
|
+
"esm"
|
|
115
|
+
],
|
|
116
|
+
dts: {
|
|
117
|
+
resolve: true
|
|
118
|
+
},
|
|
119
|
+
clean: true,
|
|
120
|
+
noExternal: [
|
|
121
|
+
"@raindrop-ai/core"
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
publishConfig: {
|
|
125
|
+
access: "public"
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
// src/package-info.ts
|
|
130
|
+
var PLUGIN_NAME = package_default.name;
|
|
131
|
+
var PLUGIN_VERSION = package_default.version;
|
|
132
|
+
|
|
56
133
|
// ../core/dist/chunk-FTBZHS25.js
|
|
57
134
|
function getCrypto() {
|
|
58
135
|
const c = globalThis.crypto;
|
|
@@ -636,70 +713,6 @@ var TraceShipper = class {
|
|
|
636
713
|
}
|
|
637
714
|
};
|
|
638
715
|
|
|
639
|
-
// package.json
|
|
640
|
-
var package_default = {
|
|
641
|
-
name: "@raindrop-ai/opencode-plugin",
|
|
642
|
-
version: "0.0.5",
|
|
643
|
-
description: "Raindrop observability plugin for OpenCode \u2014 automatic session/event/span tracing",
|
|
644
|
-
type: "module",
|
|
645
|
-
main: "dist/index.cjs",
|
|
646
|
-
module: "dist/index.js",
|
|
647
|
-
types: "dist/index.d.ts",
|
|
648
|
-
exports: {
|
|
649
|
-
".": {
|
|
650
|
-
types: "./dist/index.d.ts",
|
|
651
|
-
import: "./dist/index.js",
|
|
652
|
-
require: "./dist/index.cjs"
|
|
653
|
-
}
|
|
654
|
-
},
|
|
655
|
-
sideEffects: false,
|
|
656
|
-
files: [
|
|
657
|
-
"dist/**"
|
|
658
|
-
],
|
|
659
|
-
scripts: {
|
|
660
|
-
build: "tsup",
|
|
661
|
-
dev: "tsup --watch",
|
|
662
|
-
clean: "rm -rf dist",
|
|
663
|
-
test: "cd tests && yarn test"
|
|
664
|
-
},
|
|
665
|
-
peerDependencies: {
|
|
666
|
-
"@opencode-ai/plugin": ">=1.2.0",
|
|
667
|
-
"@opencode-ai/sdk": ">=1.2.0"
|
|
668
|
-
},
|
|
669
|
-
peerDependenciesMeta: {
|
|
670
|
-
"@opencode-ai/sdk": {
|
|
671
|
-
optional: true
|
|
672
|
-
}
|
|
673
|
-
},
|
|
674
|
-
devDependencies: {
|
|
675
|
-
"@raindrop-ai/core": "*",
|
|
676
|
-
"@opencode-ai/plugin": "^1.2.0",
|
|
677
|
-
"@opencode-ai/sdk": "^1.2.0",
|
|
678
|
-
"@types/node": "^20.11.17",
|
|
679
|
-
tsup: "^8.4.0",
|
|
680
|
-
typescript: "^5.3.3"
|
|
681
|
-
},
|
|
682
|
-
tsup: {
|
|
683
|
-
entry: [
|
|
684
|
-
"src/index.ts"
|
|
685
|
-
],
|
|
686
|
-
format: [
|
|
687
|
-
"cjs",
|
|
688
|
-
"esm"
|
|
689
|
-
],
|
|
690
|
-
dts: {
|
|
691
|
-
resolve: true
|
|
692
|
-
},
|
|
693
|
-
clean: true,
|
|
694
|
-
noExternal: [
|
|
695
|
-
"@raindrop-ai/core"
|
|
696
|
-
]
|
|
697
|
-
},
|
|
698
|
-
publishConfig: {
|
|
699
|
-
access: "public"
|
|
700
|
-
}
|
|
701
|
-
};
|
|
702
|
-
|
|
703
716
|
// src/shipper.ts
|
|
704
717
|
var EventShipper2 = class extends EventShipper {
|
|
705
718
|
constructor(opts) {
|
|
@@ -707,8 +720,8 @@ var EventShipper2 = class extends EventShipper {
|
|
|
707
720
|
super({
|
|
708
721
|
...opts,
|
|
709
722
|
sdkName: (_a = opts.sdkName) != null ? _a : "opencode-plugin",
|
|
710
|
-
libraryName: (_b = opts.libraryName) != null ? _b :
|
|
711
|
-
libraryVersion: (_c = opts.libraryVersion) != null ? _c :
|
|
723
|
+
libraryName: (_b = opts.libraryName) != null ? _b : PLUGIN_NAME,
|
|
724
|
+
libraryVersion: (_c = opts.libraryVersion) != null ? _c : PLUGIN_VERSION,
|
|
712
725
|
defaultEventName: (_d = opts.defaultEventName) != null ? _d : "opencode_session"
|
|
713
726
|
});
|
|
714
727
|
}
|
|
@@ -720,7 +733,7 @@ var TraceShipper2 = class extends TraceShipper {
|
|
|
720
733
|
...opts,
|
|
721
734
|
sdkName: (_a = opts.sdkName) != null ? _a : "opencode-plugin",
|
|
722
735
|
serviceName: (_b = opts.serviceName) != null ? _b : "raindrop.opencode-plugin",
|
|
723
|
-
serviceVersion: (_c = opts.serviceVersion) != null ? _c :
|
|
736
|
+
serviceVersion: (_c = opts.serviceVersion) != null ? _c : PLUGIN_VERSION
|
|
724
737
|
});
|
|
725
738
|
}
|
|
726
739
|
enqueue(span) {
|
|
@@ -820,8 +833,6 @@ var pendingChildSessionsByCallKey = /* @__PURE__ */ new Map();
|
|
|
820
833
|
function createSessionState(sessionId) {
|
|
821
834
|
return {
|
|
822
835
|
sessionId,
|
|
823
|
-
turnNumber: 0,
|
|
824
|
-
toolCount: 0,
|
|
825
836
|
currentInput: "",
|
|
826
837
|
outputParts: /* @__PURE__ */ new Map(),
|
|
827
838
|
reasoningParts: /* @__PURE__ */ new Map(),
|
|
@@ -875,7 +886,7 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
875
886
|
// event — session lifecycle + streaming parts
|
|
876
887
|
// ------------------------------------------------------------------
|
|
877
888
|
event: async ({ event }) => {
|
|
878
|
-
var _a, _b, _c, _d, _e;
|
|
889
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
879
890
|
try {
|
|
880
891
|
const props = event.properties;
|
|
881
892
|
const info = props["info"];
|
|
@@ -1093,12 +1104,11 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
1093
1104
|
}
|
|
1094
1105
|
if (!state.parentId) {
|
|
1095
1106
|
await eventShipper.finish(state.currentEventId, {
|
|
1096
|
-
userId: state.sessionId,
|
|
1107
|
+
userId: (_d = (_c = state.eventMetadata) == null ? void 0 : _c.userId) != null ? _d : state.sessionId,
|
|
1097
1108
|
model: modelName,
|
|
1098
1109
|
output: outputText,
|
|
1099
1110
|
properties: {
|
|
1100
|
-
|
|
1101
|
-
tool_count: state.toolCount
|
|
1111
|
+
plugin_version: PLUGIN_VERSION
|
|
1102
1112
|
}
|
|
1103
1113
|
});
|
|
1104
1114
|
}
|
|
@@ -1136,7 +1146,7 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
1136
1146
|
await Promise.all([eventShipper.flush(), traceShipper.flush()]);
|
|
1137
1147
|
sessions.delete(String(sessionID));
|
|
1138
1148
|
} else if (event.type === "session.error") {
|
|
1139
|
-
const errorSessionID = (
|
|
1149
|
+
const errorSessionID = (_e = props["sessionID"]) != null ? _e : sessionID;
|
|
1140
1150
|
if (errorSessionID === void 0 || errorSessionID === "")
|
|
1141
1151
|
throw new Error("session.error: missing sessionID");
|
|
1142
1152
|
const state = sessions.get(String(errorSessionID));
|
|
@@ -1144,7 +1154,7 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
1144
1154
|
const errorObj = props["error"];
|
|
1145
1155
|
if (errorObj == null) throw new Error("session.error: missing error object");
|
|
1146
1156
|
const errorName = errorObj.name;
|
|
1147
|
-
const errorMessage = (
|
|
1157
|
+
const errorMessage = (_g = (_f = errorObj.data) == null ? void 0 : _f.message) != null ? _g : errorObj.name;
|
|
1148
1158
|
if (errorName == null && errorMessage == null)
|
|
1149
1159
|
throw new Error("session.error: error object must have name or data.message");
|
|
1150
1160
|
const errorStr = `${errorMessage != null ? errorMessage : errorName}
|
|
@@ -1171,6 +1181,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1171
1181
|
// chat.message — user sent a message; start a new turn with a fresh event ID
|
|
1172
1182
|
// ------------------------------------------------------------------
|
|
1173
1183
|
"chat.message": async (messageInput, output) => {
|
|
1184
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1174
1185
|
try {
|
|
1175
1186
|
const { sessionID } = messageInput;
|
|
1176
1187
|
let state = sessions.get(sessionID);
|
|
@@ -1183,15 +1194,24 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1183
1194
|
traceShipper.endSpan(state.currentRootSpan);
|
|
1184
1195
|
state.currentRootSpan = void 0;
|
|
1185
1196
|
}
|
|
1186
|
-
state.turnNumber++;
|
|
1187
1197
|
if (output == null) throw new Error("chat.message: output is required");
|
|
1188
1198
|
const parts = output.parts;
|
|
1189
1199
|
if (parts == null) throw new Error("chat.message: output.parts is required");
|
|
1190
1200
|
const textParts = [];
|
|
1191
1201
|
const newAttachments = [];
|
|
1202
|
+
const baseMeta = { ...config.eventMetadata };
|
|
1203
|
+
const promptMeta = {};
|
|
1192
1204
|
for (const part of parts) {
|
|
1193
1205
|
if (part["type"] === "text" && typeof part["text"] === "string") {
|
|
1194
1206
|
textParts.push(part["text"]);
|
|
1207
|
+
const meta = part["metadata"];
|
|
1208
|
+
if (meta != null && typeof meta === "object") {
|
|
1209
|
+
const m = meta;
|
|
1210
|
+
if (typeof m["userId"] === "string") promptMeta.userId = m["userId"];
|
|
1211
|
+
if (typeof m["eventName"] === "string") promptMeta.eventName = m["eventName"];
|
|
1212
|
+
if (m["properties"] != null && typeof m["properties"] === "object")
|
|
1213
|
+
promptMeta.properties = m["properties"];
|
|
1214
|
+
}
|
|
1195
1215
|
} else if (part["type"] === "file") {
|
|
1196
1216
|
const mimeType = part["mediaType"];
|
|
1197
1217
|
const filename = part["filename"];
|
|
@@ -1203,6 +1223,11 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1203
1223
|
}
|
|
1204
1224
|
}
|
|
1205
1225
|
}
|
|
1226
|
+
state.eventMetadata = {
|
|
1227
|
+
...baseMeta,
|
|
1228
|
+
...promptMeta,
|
|
1229
|
+
properties: baseMeta.properties || promptMeta.properties ? { ...(_a = baseMeta.properties) != null ? _a : {}, ...(_b = promptMeta.properties) != null ? _b : {} } : void 0
|
|
1230
|
+
};
|
|
1206
1231
|
const userText = textParts.join("\n");
|
|
1207
1232
|
state.currentInput = userText;
|
|
1208
1233
|
if (state.parentId) {
|
|
@@ -1238,9 +1263,9 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1238
1263
|
});
|
|
1239
1264
|
await eventShipper.patch(state.currentEventId, {
|
|
1240
1265
|
isPending: true,
|
|
1241
|
-
userId: state.sessionId,
|
|
1266
|
+
userId: (_d = (_c = state.eventMetadata) == null ? void 0 : _c.userId) != null ? _d : state.sessionId,
|
|
1242
1267
|
convoId: state.sessionId,
|
|
1243
|
-
eventName: config.eventName,
|
|
1268
|
+
eventName: (_f = (_e = state.eventMetadata) == null ? void 0 : _e.eventName) != null ? _f : config.eventName,
|
|
1244
1269
|
input: userText,
|
|
1245
1270
|
...newAttachments.length > 0 ? { attachments: newAttachments } : {},
|
|
1246
1271
|
properties: {
|
|
@@ -1248,8 +1273,8 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1248
1273
|
directory,
|
|
1249
1274
|
hostname,
|
|
1250
1275
|
os,
|
|
1251
|
-
|
|
1252
|
-
|
|
1276
|
+
plugin_version: PLUGIN_VERSION,
|
|
1277
|
+
...(_g = state.eventMetadata) == null ? void 0 : _g.properties
|
|
1253
1278
|
}
|
|
1254
1279
|
});
|
|
1255
1280
|
} catch (err) {
|
|
@@ -1260,7 +1285,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1260
1285
|
// For child sessions, tool spans are parented directly to the parent task span.
|
|
1261
1286
|
// ------------------------------------------------------------------
|
|
1262
1287
|
"tool.execute.before": async (toolInput, _output) => {
|
|
1263
|
-
var _a;
|
|
1288
|
+
var _a, _b, _c;
|
|
1264
1289
|
try {
|
|
1265
1290
|
const { tool, sessionID, callID } = toolInput;
|
|
1266
1291
|
const state = sessions.get(sessionID);
|
|
@@ -1284,7 +1309,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1284
1309
|
ids: liveTaskSpan.ids,
|
|
1285
1310
|
eventContext: {
|
|
1286
1311
|
eventId: state.currentEventId,
|
|
1287
|
-
userId: state.sessionId,
|
|
1312
|
+
userId: (_c = (_b = state.eventMetadata) == null ? void 0 : _b.userId) != null ? _c : state.sessionId,
|
|
1288
1313
|
convoId: state.sessionId
|
|
1289
1314
|
}
|
|
1290
1315
|
};
|
|
@@ -1325,7 +1350,6 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1325
1350
|
const { tool, sessionID, callID, args } = toolInput;
|
|
1326
1351
|
const state = sessions.get(sessionID);
|
|
1327
1352
|
if (!state || !state.currentEventId) return;
|
|
1328
|
-
state.toolCount++;
|
|
1329
1353
|
if (args === void 0 || args === null)
|
|
1330
1354
|
throw new Error("tool.execute.after: args is required");
|
|
1331
1355
|
const toolCallArgs = typeof args === "string" ? args : JSON.stringify(args);
|
|
@@ -1379,12 +1403,6 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1379
1403
|
if (running.size === 0) runningTaskCallsBySession.delete(sessionID);
|
|
1380
1404
|
}
|
|
1381
1405
|
}
|
|
1382
|
-
if (!state.parentId) {
|
|
1383
|
-
await eventShipper.patch(state.currentEventId, {
|
|
1384
|
-
userId: state.sessionId,
|
|
1385
|
-
properties: { tool_count: state.toolCount }
|
|
1386
|
-
});
|
|
1387
|
-
}
|
|
1388
1406
|
} catch (err) {
|
|
1389
1407
|
console.log(
|
|
1390
1408
|
`[raindrop-ai/opencode-plugin] [error] Error in tool.execute.after hook: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -1401,6 +1419,7 @@ async function plugin(input) {
|
|
|
1401
1419
|
function appLog(level, message) {
|
|
1402
1420
|
console.log(`[raindrop-ai/opencode-plugin] [${level}] ${message}`);
|
|
1403
1421
|
}
|
|
1422
|
+
appLog("info", `Loading ${PLUGIN_NAME} v${PLUGIN_VERSION}`);
|
|
1404
1423
|
if (!config.writeKey) {
|
|
1405
1424
|
appLog(
|
|
1406
1425
|
"warn",
|
package/dist/index.js
CHANGED
|
@@ -26,14 +26,91 @@ function loadConfig(projectDirectory) {
|
|
|
26
26
|
} catch (e) {
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
+
let eventMetadata;
|
|
30
|
+
const envMeta = process.env["RAINDROP_EVENT_METADATA"];
|
|
31
|
+
if (envMeta) {
|
|
32
|
+
try {
|
|
33
|
+
eventMetadata = JSON.parse(envMeta);
|
|
34
|
+
} catch (e) {
|
|
35
|
+
}
|
|
36
|
+
}
|
|
29
37
|
return {
|
|
30
38
|
writeKey: (_b = (_a = process.env["RAINDROP_WRITE_KEY"]) != null ? _a : merged.write_key) != null ? _b : "",
|
|
31
39
|
endpoint: (_d = (_c = process.env["RAINDROP_API_URL"]) != null ? _c : merged.api_url) != null ? _d : "https://api.raindrop.ai/v1",
|
|
32
40
|
eventName: (_e = merged.event_name) != null ? _e : "opencode_session",
|
|
33
|
-
debug: process.env["RAINDROP_DEBUG"] === "true" ? true : (_f = merged.debug) != null ? _f : false
|
|
41
|
+
debug: process.env["RAINDROP_DEBUG"] === "true" ? true : (_f = merged.debug) != null ? _f : false,
|
|
42
|
+
eventMetadata
|
|
34
43
|
};
|
|
35
44
|
}
|
|
36
45
|
|
|
46
|
+
// package.json
|
|
47
|
+
var package_default = {
|
|
48
|
+
name: "@raindrop-ai/opencode-plugin",
|
|
49
|
+
version: "0.0.6",
|
|
50
|
+
description: "Raindrop observability plugin for OpenCode \u2014 automatic session/event/span tracing",
|
|
51
|
+
type: "module",
|
|
52
|
+
main: "dist/index.cjs",
|
|
53
|
+
module: "dist/index.js",
|
|
54
|
+
types: "dist/index.d.ts",
|
|
55
|
+
exports: {
|
|
56
|
+
".": {
|
|
57
|
+
types: "./dist/index.d.ts",
|
|
58
|
+
import: "./dist/index.js",
|
|
59
|
+
require: "./dist/index.cjs"
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
sideEffects: false,
|
|
63
|
+
files: [
|
|
64
|
+
"dist/**"
|
|
65
|
+
],
|
|
66
|
+
scripts: {
|
|
67
|
+
build: "tsup",
|
|
68
|
+
dev: "tsup --watch",
|
|
69
|
+
clean: "rm -rf dist",
|
|
70
|
+
test: "cd tests && pnpm test"
|
|
71
|
+
},
|
|
72
|
+
peerDependencies: {
|
|
73
|
+
"@opencode-ai/plugin": ">=1.2.0",
|
|
74
|
+
"@opencode-ai/sdk": ">=1.2.0"
|
|
75
|
+
},
|
|
76
|
+
peerDependenciesMeta: {
|
|
77
|
+
"@opencode-ai/sdk": {
|
|
78
|
+
optional: true
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
devDependencies: {
|
|
82
|
+
"@raindrop-ai/core": "workspace:*",
|
|
83
|
+
"@opencode-ai/plugin": "^1.2.0",
|
|
84
|
+
"@opencode-ai/sdk": "^1.2.0",
|
|
85
|
+
"@types/node": "^20.11.17",
|
|
86
|
+
tsup: "^8.4.0",
|
|
87
|
+
typescript: "^5.3.3"
|
|
88
|
+
},
|
|
89
|
+
tsup: {
|
|
90
|
+
entry: [
|
|
91
|
+
"src/index.ts"
|
|
92
|
+
],
|
|
93
|
+
format: [
|
|
94
|
+
"cjs",
|
|
95
|
+
"esm"
|
|
96
|
+
],
|
|
97
|
+
dts: {
|
|
98
|
+
resolve: true
|
|
99
|
+
},
|
|
100
|
+
clean: true,
|
|
101
|
+
noExternal: [
|
|
102
|
+
"@raindrop-ai/core"
|
|
103
|
+
]
|
|
104
|
+
},
|
|
105
|
+
publishConfig: {
|
|
106
|
+
access: "public"
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// src/package-info.ts
|
|
111
|
+
var PLUGIN_NAME = package_default.name;
|
|
112
|
+
var PLUGIN_VERSION = package_default.version;
|
|
113
|
+
|
|
37
114
|
// ../core/dist/chunk-FTBZHS25.js
|
|
38
115
|
function getCrypto() {
|
|
39
116
|
const c = globalThis.crypto;
|
|
@@ -617,70 +694,6 @@ var TraceShipper = class {
|
|
|
617
694
|
}
|
|
618
695
|
};
|
|
619
696
|
|
|
620
|
-
// package.json
|
|
621
|
-
var package_default = {
|
|
622
|
-
name: "@raindrop-ai/opencode-plugin",
|
|
623
|
-
version: "0.0.5",
|
|
624
|
-
description: "Raindrop observability plugin for OpenCode \u2014 automatic session/event/span tracing",
|
|
625
|
-
type: "module",
|
|
626
|
-
main: "dist/index.cjs",
|
|
627
|
-
module: "dist/index.js",
|
|
628
|
-
types: "dist/index.d.ts",
|
|
629
|
-
exports: {
|
|
630
|
-
".": {
|
|
631
|
-
types: "./dist/index.d.ts",
|
|
632
|
-
import: "./dist/index.js",
|
|
633
|
-
require: "./dist/index.cjs"
|
|
634
|
-
}
|
|
635
|
-
},
|
|
636
|
-
sideEffects: false,
|
|
637
|
-
files: [
|
|
638
|
-
"dist/**"
|
|
639
|
-
],
|
|
640
|
-
scripts: {
|
|
641
|
-
build: "tsup",
|
|
642
|
-
dev: "tsup --watch",
|
|
643
|
-
clean: "rm -rf dist",
|
|
644
|
-
test: "cd tests && yarn test"
|
|
645
|
-
},
|
|
646
|
-
peerDependencies: {
|
|
647
|
-
"@opencode-ai/plugin": ">=1.2.0",
|
|
648
|
-
"@opencode-ai/sdk": ">=1.2.0"
|
|
649
|
-
},
|
|
650
|
-
peerDependenciesMeta: {
|
|
651
|
-
"@opencode-ai/sdk": {
|
|
652
|
-
optional: true
|
|
653
|
-
}
|
|
654
|
-
},
|
|
655
|
-
devDependencies: {
|
|
656
|
-
"@raindrop-ai/core": "*",
|
|
657
|
-
"@opencode-ai/plugin": "^1.2.0",
|
|
658
|
-
"@opencode-ai/sdk": "^1.2.0",
|
|
659
|
-
"@types/node": "^20.11.17",
|
|
660
|
-
tsup: "^8.4.0",
|
|
661
|
-
typescript: "^5.3.3"
|
|
662
|
-
},
|
|
663
|
-
tsup: {
|
|
664
|
-
entry: [
|
|
665
|
-
"src/index.ts"
|
|
666
|
-
],
|
|
667
|
-
format: [
|
|
668
|
-
"cjs",
|
|
669
|
-
"esm"
|
|
670
|
-
],
|
|
671
|
-
dts: {
|
|
672
|
-
resolve: true
|
|
673
|
-
},
|
|
674
|
-
clean: true,
|
|
675
|
-
noExternal: [
|
|
676
|
-
"@raindrop-ai/core"
|
|
677
|
-
]
|
|
678
|
-
},
|
|
679
|
-
publishConfig: {
|
|
680
|
-
access: "public"
|
|
681
|
-
}
|
|
682
|
-
};
|
|
683
|
-
|
|
684
697
|
// src/shipper.ts
|
|
685
698
|
var EventShipper2 = class extends EventShipper {
|
|
686
699
|
constructor(opts) {
|
|
@@ -688,8 +701,8 @@ var EventShipper2 = class extends EventShipper {
|
|
|
688
701
|
super({
|
|
689
702
|
...opts,
|
|
690
703
|
sdkName: (_a = opts.sdkName) != null ? _a : "opencode-plugin",
|
|
691
|
-
libraryName: (_b = opts.libraryName) != null ? _b :
|
|
692
|
-
libraryVersion: (_c = opts.libraryVersion) != null ? _c :
|
|
704
|
+
libraryName: (_b = opts.libraryName) != null ? _b : PLUGIN_NAME,
|
|
705
|
+
libraryVersion: (_c = opts.libraryVersion) != null ? _c : PLUGIN_VERSION,
|
|
693
706
|
defaultEventName: (_d = opts.defaultEventName) != null ? _d : "opencode_session"
|
|
694
707
|
});
|
|
695
708
|
}
|
|
@@ -701,7 +714,7 @@ var TraceShipper2 = class extends TraceShipper {
|
|
|
701
714
|
...opts,
|
|
702
715
|
sdkName: (_a = opts.sdkName) != null ? _a : "opencode-plugin",
|
|
703
716
|
serviceName: (_b = opts.serviceName) != null ? _b : "raindrop.opencode-plugin",
|
|
704
|
-
serviceVersion: (_c = opts.serviceVersion) != null ? _c :
|
|
717
|
+
serviceVersion: (_c = opts.serviceVersion) != null ? _c : PLUGIN_VERSION
|
|
705
718
|
});
|
|
706
719
|
}
|
|
707
720
|
enqueue(span) {
|
|
@@ -801,8 +814,6 @@ var pendingChildSessionsByCallKey = /* @__PURE__ */ new Map();
|
|
|
801
814
|
function createSessionState(sessionId) {
|
|
802
815
|
return {
|
|
803
816
|
sessionId,
|
|
804
|
-
turnNumber: 0,
|
|
805
|
-
toolCount: 0,
|
|
806
817
|
currentInput: "",
|
|
807
818
|
outputParts: /* @__PURE__ */ new Map(),
|
|
808
819
|
reasoningParts: /* @__PURE__ */ new Map(),
|
|
@@ -856,7 +867,7 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
856
867
|
// event — session lifecycle + streaming parts
|
|
857
868
|
// ------------------------------------------------------------------
|
|
858
869
|
event: async ({ event }) => {
|
|
859
|
-
var _a, _b, _c, _d, _e;
|
|
870
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
860
871
|
try {
|
|
861
872
|
const props = event.properties;
|
|
862
873
|
const info = props["info"];
|
|
@@ -1074,12 +1085,11 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
1074
1085
|
}
|
|
1075
1086
|
if (!state.parentId) {
|
|
1076
1087
|
await eventShipper.finish(state.currentEventId, {
|
|
1077
|
-
userId: state.sessionId,
|
|
1088
|
+
userId: (_d = (_c = state.eventMetadata) == null ? void 0 : _c.userId) != null ? _d : state.sessionId,
|
|
1078
1089
|
model: modelName,
|
|
1079
1090
|
output: outputText,
|
|
1080
1091
|
properties: {
|
|
1081
|
-
|
|
1082
|
-
tool_count: state.toolCount
|
|
1092
|
+
plugin_version: PLUGIN_VERSION
|
|
1083
1093
|
}
|
|
1084
1094
|
});
|
|
1085
1095
|
}
|
|
@@ -1117,7 +1127,7 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
1117
1127
|
await Promise.all([eventShipper.flush(), traceShipper.flush()]);
|
|
1118
1128
|
sessions.delete(String(sessionID));
|
|
1119
1129
|
} else if (event.type === "session.error") {
|
|
1120
|
-
const errorSessionID = (
|
|
1130
|
+
const errorSessionID = (_e = props["sessionID"]) != null ? _e : sessionID;
|
|
1121
1131
|
if (errorSessionID === void 0 || errorSessionID === "")
|
|
1122
1132
|
throw new Error("session.error: missing sessionID");
|
|
1123
1133
|
const state = sessions.get(String(errorSessionID));
|
|
@@ -1125,7 +1135,7 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
1125
1135
|
const errorObj = props["error"];
|
|
1126
1136
|
if (errorObj == null) throw new Error("session.error: missing error object");
|
|
1127
1137
|
const errorName = errorObj.name;
|
|
1128
|
-
const errorMessage = (
|
|
1138
|
+
const errorMessage = (_g = (_f = errorObj.data) == null ? void 0 : _f.message) != null ? _g : errorObj.name;
|
|
1129
1139
|
if (errorName == null && errorMessage == null)
|
|
1130
1140
|
throw new Error("session.error: error object must have name or data.message");
|
|
1131
1141
|
const errorStr = `${errorMessage != null ? errorMessage : errorName}
|
|
@@ -1152,6 +1162,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1152
1162
|
// chat.message — user sent a message; start a new turn with a fresh event ID
|
|
1153
1163
|
// ------------------------------------------------------------------
|
|
1154
1164
|
"chat.message": async (messageInput, output) => {
|
|
1165
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1155
1166
|
try {
|
|
1156
1167
|
const { sessionID } = messageInput;
|
|
1157
1168
|
let state = sessions.get(sessionID);
|
|
@@ -1164,15 +1175,24 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1164
1175
|
traceShipper.endSpan(state.currentRootSpan);
|
|
1165
1176
|
state.currentRootSpan = void 0;
|
|
1166
1177
|
}
|
|
1167
|
-
state.turnNumber++;
|
|
1168
1178
|
if (output == null) throw new Error("chat.message: output is required");
|
|
1169
1179
|
const parts = output.parts;
|
|
1170
1180
|
if (parts == null) throw new Error("chat.message: output.parts is required");
|
|
1171
1181
|
const textParts = [];
|
|
1172
1182
|
const newAttachments = [];
|
|
1183
|
+
const baseMeta = { ...config.eventMetadata };
|
|
1184
|
+
const promptMeta = {};
|
|
1173
1185
|
for (const part of parts) {
|
|
1174
1186
|
if (part["type"] === "text" && typeof part["text"] === "string") {
|
|
1175
1187
|
textParts.push(part["text"]);
|
|
1188
|
+
const meta = part["metadata"];
|
|
1189
|
+
if (meta != null && typeof meta === "object") {
|
|
1190
|
+
const m = meta;
|
|
1191
|
+
if (typeof m["userId"] === "string") promptMeta.userId = m["userId"];
|
|
1192
|
+
if (typeof m["eventName"] === "string") promptMeta.eventName = m["eventName"];
|
|
1193
|
+
if (m["properties"] != null && typeof m["properties"] === "object")
|
|
1194
|
+
promptMeta.properties = m["properties"];
|
|
1195
|
+
}
|
|
1176
1196
|
} else if (part["type"] === "file") {
|
|
1177
1197
|
const mimeType = part["mediaType"];
|
|
1178
1198
|
const filename = part["filename"];
|
|
@@ -1184,6 +1204,11 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1184
1204
|
}
|
|
1185
1205
|
}
|
|
1186
1206
|
}
|
|
1207
|
+
state.eventMetadata = {
|
|
1208
|
+
...baseMeta,
|
|
1209
|
+
...promptMeta,
|
|
1210
|
+
properties: baseMeta.properties || promptMeta.properties ? { ...(_a = baseMeta.properties) != null ? _a : {}, ...(_b = promptMeta.properties) != null ? _b : {} } : void 0
|
|
1211
|
+
};
|
|
1187
1212
|
const userText = textParts.join("\n");
|
|
1188
1213
|
state.currentInput = userText;
|
|
1189
1214
|
if (state.parentId) {
|
|
@@ -1219,9 +1244,9 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1219
1244
|
});
|
|
1220
1245
|
await eventShipper.patch(state.currentEventId, {
|
|
1221
1246
|
isPending: true,
|
|
1222
|
-
userId: state.sessionId,
|
|
1247
|
+
userId: (_d = (_c = state.eventMetadata) == null ? void 0 : _c.userId) != null ? _d : state.sessionId,
|
|
1223
1248
|
convoId: state.sessionId,
|
|
1224
|
-
eventName: config.eventName,
|
|
1249
|
+
eventName: (_f = (_e = state.eventMetadata) == null ? void 0 : _e.eventName) != null ? _f : config.eventName,
|
|
1225
1250
|
input: userText,
|
|
1226
1251
|
...newAttachments.length > 0 ? { attachments: newAttachments } : {},
|
|
1227
1252
|
properties: {
|
|
@@ -1229,8 +1254,8 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1229
1254
|
directory,
|
|
1230
1255
|
hostname,
|
|
1231
1256
|
os,
|
|
1232
|
-
|
|
1233
|
-
|
|
1257
|
+
plugin_version: PLUGIN_VERSION,
|
|
1258
|
+
...(_g = state.eventMetadata) == null ? void 0 : _g.properties
|
|
1234
1259
|
}
|
|
1235
1260
|
});
|
|
1236
1261
|
} catch (err) {
|
|
@@ -1241,7 +1266,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1241
1266
|
// For child sessions, tool spans are parented directly to the parent task span.
|
|
1242
1267
|
// ------------------------------------------------------------------
|
|
1243
1268
|
"tool.execute.before": async (toolInput, _output) => {
|
|
1244
|
-
var _a;
|
|
1269
|
+
var _a, _b, _c;
|
|
1245
1270
|
try {
|
|
1246
1271
|
const { tool, sessionID, callID } = toolInput;
|
|
1247
1272
|
const state = sessions.get(sessionID);
|
|
@@ -1265,7 +1290,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1265
1290
|
ids: liveTaskSpan.ids,
|
|
1266
1291
|
eventContext: {
|
|
1267
1292
|
eventId: state.currentEventId,
|
|
1268
|
-
userId: state.sessionId,
|
|
1293
|
+
userId: (_c = (_b = state.eventMetadata) == null ? void 0 : _b.userId) != null ? _c : state.sessionId,
|
|
1269
1294
|
convoId: state.sessionId
|
|
1270
1295
|
}
|
|
1271
1296
|
};
|
|
@@ -1306,7 +1331,6 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1306
1331
|
const { tool, sessionID, callID, args } = toolInput;
|
|
1307
1332
|
const state = sessions.get(sessionID);
|
|
1308
1333
|
if (!state || !state.currentEventId) return;
|
|
1309
|
-
state.toolCount++;
|
|
1310
1334
|
if (args === void 0 || args === null)
|
|
1311
1335
|
throw new Error("tool.execute.after: args is required");
|
|
1312
1336
|
const toolCallArgs = typeof args === "string" ? args : JSON.stringify(args);
|
|
@@ -1360,12 +1384,6 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1360
1384
|
if (running.size === 0) runningTaskCallsBySession.delete(sessionID);
|
|
1361
1385
|
}
|
|
1362
1386
|
}
|
|
1363
|
-
if (!state.parentId) {
|
|
1364
|
-
await eventShipper.patch(state.currentEventId, {
|
|
1365
|
-
userId: state.sessionId,
|
|
1366
|
-
properties: { tool_count: state.toolCount }
|
|
1367
|
-
});
|
|
1368
|
-
}
|
|
1369
1387
|
} catch (err) {
|
|
1370
1388
|
console.log(
|
|
1371
1389
|
`[raindrop-ai/opencode-plugin] [error] Error in tool.execute.after hook: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -1382,6 +1400,7 @@ async function plugin(input) {
|
|
|
1382
1400
|
function appLog(level, message) {
|
|
1383
1401
|
console.log(`[raindrop-ai/opencode-plugin] [${level}] ${message}`);
|
|
1384
1402
|
}
|
|
1403
|
+
appLog("info", `Loading ${PLUGIN_NAME} v${PLUGIN_VERSION}`);
|
|
1385
1404
|
if (!config.writeKey) {
|
|
1386
1405
|
appLog(
|
|
1387
1406
|
"warn",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raindrop-ai/opencode-plugin",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "Raindrop observability plugin for OpenCode — automatic session/event/span tracing",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"build": "tsup",
|
|
22
22
|
"dev": "tsup --watch",
|
|
23
23
|
"clean": "rm -rf dist",
|
|
24
|
-
"test": "cd tests &&
|
|
24
|
+
"test": "cd tests && pnpm test"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
27
|
"@opencode-ai/plugin": ">=1.2.0",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@raindrop-ai/core": "
|
|
36
|
+
"@raindrop-ai/core": "workspace:*",
|
|
37
37
|
"@opencode-ai/plugin": "^1.2.0",
|
|
38
38
|
"@opencode-ai/sdk": "^1.2.0",
|
|
39
39
|
"@types/node": "^20.11.17",
|