@raindrop-ai/opencode-plugin 0.0.9 → 0.0.11
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/LICENSE +21 -0
- package/README.md +17 -0
- package/dist/index.cjs +76 -12
- package/dist/index.js +76 -12
- package/package.json +20 -10
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Raindrop AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# `@raindrop-ai/opencode-plugin`
|
|
2
|
+
|
|
3
|
+
Raindrop observability plugin for OpenCode with automatic session, event, and span tracing.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @raindrop-ai/opencode-plugin @opencode-ai/plugin
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
If your integration also uses the OpenCode SDK directly, install `@opencode-ai/sdk` as well.
|
|
12
|
+
|
|
13
|
+
## Notes
|
|
14
|
+
|
|
15
|
+
- `@opencode-ai/plugin` is required.
|
|
16
|
+
- `@opencode-ai/sdk` is an optional peer dependency.
|
|
17
|
+
- Tests live in the nested `tests/` package and validate HTTP payloads and tracing behavior.
|
package/dist/index.cjs
CHANGED
|
@@ -66,12 +66,22 @@ function loadConfig(projectDirectory) {
|
|
|
66
66
|
// package.json
|
|
67
67
|
var package_default = {
|
|
68
68
|
name: "@raindrop-ai/opencode-plugin",
|
|
69
|
-
version: "0.0.
|
|
69
|
+
version: "0.0.11",
|
|
70
70
|
description: "Raindrop observability plugin for OpenCode \u2014 automatic session/event/span tracing",
|
|
71
71
|
type: "module",
|
|
72
72
|
main: "dist/index.js",
|
|
73
73
|
module: "dist/index.js",
|
|
74
74
|
types: "dist/index.d.ts",
|
|
75
|
+
license: "MIT",
|
|
76
|
+
repository: {
|
|
77
|
+
type: "git",
|
|
78
|
+
url: "git+https://github.com/raindrop-ai/raindrop-js.git",
|
|
79
|
+
directory: "packages/opencode-plugin"
|
|
80
|
+
},
|
|
81
|
+
homepage: "https://github.com/raindrop-ai/raindrop-js/tree/main/packages/opencode-plugin#readme",
|
|
82
|
+
bugs: {
|
|
83
|
+
url: "https://github.com/raindrop-ai/raindrop-js/issues"
|
|
84
|
+
},
|
|
75
85
|
exports: {
|
|
76
86
|
".": {
|
|
77
87
|
types: "./dist/index.d.ts",
|
|
@@ -909,6 +919,46 @@ function createSessionState(sessionId) {
|
|
|
909
919
|
function callKey(sessionId, callId) {
|
|
910
920
|
return `${sessionId}:${callId}`;
|
|
911
921
|
}
|
|
922
|
+
function markTaskCallFinished(sessionID, callID) {
|
|
923
|
+
const running = runningTaskCallsBySession.get(sessionID);
|
|
924
|
+
if (!running) return;
|
|
925
|
+
running.delete(callID);
|
|
926
|
+
if (running.size === 0) runningTaskCallsBySession.delete(sessionID);
|
|
927
|
+
}
|
|
928
|
+
function endPendingToolSpanWithError(state, callID, tool, toolCallArgs, errorMessage, traceShipper) {
|
|
929
|
+
const startInfo = state.toolSpanStarts.get(callID);
|
|
930
|
+
if (!startInfo) return false;
|
|
931
|
+
state.toolSpanStarts.delete(callID);
|
|
932
|
+
const error = new Error(errorMessage);
|
|
933
|
+
const endAttrs = [
|
|
934
|
+
attrString("ai.toolCall.args", toolCallArgs),
|
|
935
|
+
attrString("error.message", errorMessage)
|
|
936
|
+
];
|
|
937
|
+
if (startInfo.liveSpan) {
|
|
938
|
+
traceShipper.endSpan(startInfo.liveSpan, {
|
|
939
|
+
attributes: endAttrs,
|
|
940
|
+
error
|
|
941
|
+
});
|
|
942
|
+
} else {
|
|
943
|
+
const toolSpan = traceShipper.startSpan({
|
|
944
|
+
name: "ai.toolCall",
|
|
945
|
+
parent: startInfo.parent,
|
|
946
|
+
eventId: startInfo.eventId,
|
|
947
|
+
startTimeUnixNano: startInfo.startTimeUnixNano,
|
|
948
|
+
attributes: [
|
|
949
|
+
attrString("ai.operationId", "ai.toolCall"),
|
|
950
|
+
attrString("ai.toolCall.name", tool),
|
|
951
|
+
attrString("ai.toolCall.id", callID)
|
|
952
|
+
]
|
|
953
|
+
});
|
|
954
|
+
traceShipper.endSpan(toolSpan, {
|
|
955
|
+
attributes: endAttrs,
|
|
956
|
+
error,
|
|
957
|
+
endTimeUnixNano: nowUnixNanoString()
|
|
958
|
+
});
|
|
959
|
+
}
|
|
960
|
+
return true;
|
|
961
|
+
}
|
|
912
962
|
function getHostname() {
|
|
913
963
|
var _a;
|
|
914
964
|
try {
|
|
@@ -993,13 +1043,13 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
993
1043
|
state.outputParts.set(messageId, partObj["text"]);
|
|
994
1044
|
} else if (partObj["type"] === "tool" && messageId) {
|
|
995
1045
|
const tool = partObj["tool"];
|
|
1046
|
+
const callID = partObj["callID"];
|
|
1047
|
+
const partState = partObj["state"];
|
|
1048
|
+
if (callID == null || callID === "")
|
|
1049
|
+
throw new Error("message.part.updated: part.callID is required for tool part");
|
|
1050
|
+
if (partState == null || typeof partState !== "object")
|
|
1051
|
+
throw new Error("message.part.updated: part.state is required for tool part");
|
|
996
1052
|
if (tool === "task") {
|
|
997
|
-
const callID = partObj["callID"];
|
|
998
|
-
const partState = partObj["state"];
|
|
999
|
-
if (callID == null || callID === "")
|
|
1000
|
-
throw new Error("message.part.updated: part.callID is required for tool part");
|
|
1001
|
-
if (partState == null || typeof partState !== "object")
|
|
1002
|
-
throw new Error("message.part.updated: part.state is required for tool part");
|
|
1003
1053
|
const metadata = partState["metadata"];
|
|
1004
1054
|
const childSessionId = metadata != null && typeof metadata === "object" ? metadata["sessionId"] : void 0;
|
|
1005
1055
|
if (childSessionId != null && childSessionId !== "") {
|
|
@@ -1014,6 +1064,24 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
1014
1064
|
);
|
|
1015
1065
|
}
|
|
1016
1066
|
}
|
|
1067
|
+
const toolState = partState;
|
|
1068
|
+
if (toolState["status"] === "error") {
|
|
1069
|
+
const errorMessage = toolState["error"];
|
|
1070
|
+
if (typeof errorMessage !== "string" || errorMessage === "")
|
|
1071
|
+
throw new Error("message.part.updated: error tool state must have error string");
|
|
1072
|
+
const input = toolState["input"];
|
|
1073
|
+
const toolCallArgs = input === void 0 ? void 0 : typeof input === "string" ? input : JSON.stringify(input);
|
|
1074
|
+
if (endPendingToolSpanWithError(
|
|
1075
|
+
state,
|
|
1076
|
+
callID,
|
|
1077
|
+
tool,
|
|
1078
|
+
toolCallArgs,
|
|
1079
|
+
errorMessage,
|
|
1080
|
+
traceShipper
|
|
1081
|
+
) && tool === "task") {
|
|
1082
|
+
markTaskCallFinished(partSessionID, callID);
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1017
1085
|
} else if (partObj["type"] === "reasoning" && typeof partObj["text"] === "string") {
|
|
1018
1086
|
state.reasoningParts.set(messageId, partObj["text"]);
|
|
1019
1087
|
}
|
|
@@ -1497,11 +1565,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1497
1565
|
}
|
|
1498
1566
|
}
|
|
1499
1567
|
if (tool === "task") {
|
|
1500
|
-
|
|
1501
|
-
if (running) {
|
|
1502
|
-
running.delete(callID);
|
|
1503
|
-
if (running.size === 0) runningTaskCallsBySession.delete(sessionID);
|
|
1504
|
-
}
|
|
1568
|
+
markTaskCallFinished(sessionID, callID);
|
|
1505
1569
|
}
|
|
1506
1570
|
} catch (err) {
|
|
1507
1571
|
console.log(
|
package/dist/index.js
CHANGED
|
@@ -47,12 +47,22 @@ function loadConfig(projectDirectory) {
|
|
|
47
47
|
// package.json
|
|
48
48
|
var package_default = {
|
|
49
49
|
name: "@raindrop-ai/opencode-plugin",
|
|
50
|
-
version: "0.0.
|
|
50
|
+
version: "0.0.11",
|
|
51
51
|
description: "Raindrop observability plugin for OpenCode \u2014 automatic session/event/span tracing",
|
|
52
52
|
type: "module",
|
|
53
53
|
main: "dist/index.js",
|
|
54
54
|
module: "dist/index.js",
|
|
55
55
|
types: "dist/index.d.ts",
|
|
56
|
+
license: "MIT",
|
|
57
|
+
repository: {
|
|
58
|
+
type: "git",
|
|
59
|
+
url: "git+https://github.com/raindrop-ai/raindrop-js.git",
|
|
60
|
+
directory: "packages/opencode-plugin"
|
|
61
|
+
},
|
|
62
|
+
homepage: "https://github.com/raindrop-ai/raindrop-js/tree/main/packages/opencode-plugin#readme",
|
|
63
|
+
bugs: {
|
|
64
|
+
url: "https://github.com/raindrop-ai/raindrop-js/issues"
|
|
65
|
+
},
|
|
56
66
|
exports: {
|
|
57
67
|
".": {
|
|
58
68
|
types: "./dist/index.d.ts",
|
|
@@ -890,6 +900,46 @@ function createSessionState(sessionId) {
|
|
|
890
900
|
function callKey(sessionId, callId) {
|
|
891
901
|
return `${sessionId}:${callId}`;
|
|
892
902
|
}
|
|
903
|
+
function markTaskCallFinished(sessionID, callID) {
|
|
904
|
+
const running = runningTaskCallsBySession.get(sessionID);
|
|
905
|
+
if (!running) return;
|
|
906
|
+
running.delete(callID);
|
|
907
|
+
if (running.size === 0) runningTaskCallsBySession.delete(sessionID);
|
|
908
|
+
}
|
|
909
|
+
function endPendingToolSpanWithError(state, callID, tool, toolCallArgs, errorMessage, traceShipper) {
|
|
910
|
+
const startInfo = state.toolSpanStarts.get(callID);
|
|
911
|
+
if (!startInfo) return false;
|
|
912
|
+
state.toolSpanStarts.delete(callID);
|
|
913
|
+
const error = new Error(errorMessage);
|
|
914
|
+
const endAttrs = [
|
|
915
|
+
attrString("ai.toolCall.args", toolCallArgs),
|
|
916
|
+
attrString("error.message", errorMessage)
|
|
917
|
+
];
|
|
918
|
+
if (startInfo.liveSpan) {
|
|
919
|
+
traceShipper.endSpan(startInfo.liveSpan, {
|
|
920
|
+
attributes: endAttrs,
|
|
921
|
+
error
|
|
922
|
+
});
|
|
923
|
+
} else {
|
|
924
|
+
const toolSpan = traceShipper.startSpan({
|
|
925
|
+
name: "ai.toolCall",
|
|
926
|
+
parent: startInfo.parent,
|
|
927
|
+
eventId: startInfo.eventId,
|
|
928
|
+
startTimeUnixNano: startInfo.startTimeUnixNano,
|
|
929
|
+
attributes: [
|
|
930
|
+
attrString("ai.operationId", "ai.toolCall"),
|
|
931
|
+
attrString("ai.toolCall.name", tool),
|
|
932
|
+
attrString("ai.toolCall.id", callID)
|
|
933
|
+
]
|
|
934
|
+
});
|
|
935
|
+
traceShipper.endSpan(toolSpan, {
|
|
936
|
+
attributes: endAttrs,
|
|
937
|
+
error,
|
|
938
|
+
endTimeUnixNano: nowUnixNanoString()
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
return true;
|
|
942
|
+
}
|
|
893
943
|
function getHostname() {
|
|
894
944
|
var _a;
|
|
895
945
|
try {
|
|
@@ -974,13 +1024,13 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
974
1024
|
state.outputParts.set(messageId, partObj["text"]);
|
|
975
1025
|
} else if (partObj["type"] === "tool" && messageId) {
|
|
976
1026
|
const tool = partObj["tool"];
|
|
1027
|
+
const callID = partObj["callID"];
|
|
1028
|
+
const partState = partObj["state"];
|
|
1029
|
+
if (callID == null || callID === "")
|
|
1030
|
+
throw new Error("message.part.updated: part.callID is required for tool part");
|
|
1031
|
+
if (partState == null || typeof partState !== "object")
|
|
1032
|
+
throw new Error("message.part.updated: part.state is required for tool part");
|
|
977
1033
|
if (tool === "task") {
|
|
978
|
-
const callID = partObj["callID"];
|
|
979
|
-
const partState = partObj["state"];
|
|
980
|
-
if (callID == null || callID === "")
|
|
981
|
-
throw new Error("message.part.updated: part.callID is required for tool part");
|
|
982
|
-
if (partState == null || typeof partState !== "object")
|
|
983
|
-
throw new Error("message.part.updated: part.state is required for tool part");
|
|
984
1034
|
const metadata = partState["metadata"];
|
|
985
1035
|
const childSessionId = metadata != null && typeof metadata === "object" ? metadata["sessionId"] : void 0;
|
|
986
1036
|
if (childSessionId != null && childSessionId !== "") {
|
|
@@ -995,6 +1045,24 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
995
1045
|
);
|
|
996
1046
|
}
|
|
997
1047
|
}
|
|
1048
|
+
const toolState = partState;
|
|
1049
|
+
if (toolState["status"] === "error") {
|
|
1050
|
+
const errorMessage = toolState["error"];
|
|
1051
|
+
if (typeof errorMessage !== "string" || errorMessage === "")
|
|
1052
|
+
throw new Error("message.part.updated: error tool state must have error string");
|
|
1053
|
+
const input = toolState["input"];
|
|
1054
|
+
const toolCallArgs = input === void 0 ? void 0 : typeof input === "string" ? input : JSON.stringify(input);
|
|
1055
|
+
if (endPendingToolSpanWithError(
|
|
1056
|
+
state,
|
|
1057
|
+
callID,
|
|
1058
|
+
tool,
|
|
1059
|
+
toolCallArgs,
|
|
1060
|
+
errorMessage,
|
|
1061
|
+
traceShipper
|
|
1062
|
+
) && tool === "task") {
|
|
1063
|
+
markTaskCallFinished(partSessionID, callID);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
998
1066
|
} else if (partObj["type"] === "reasoning" && typeof partObj["text"] === "string") {
|
|
999
1067
|
state.reasoningParts.set(messageId, partObj["text"]);
|
|
1000
1068
|
}
|
|
@@ -1478,11 +1546,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
1478
1546
|
}
|
|
1479
1547
|
}
|
|
1480
1548
|
if (tool === "task") {
|
|
1481
|
-
|
|
1482
|
-
if (running) {
|
|
1483
|
-
running.delete(callID);
|
|
1484
|
-
if (running.size === 0) runningTaskCallsBySession.delete(sessionID);
|
|
1485
|
-
}
|
|
1549
|
+
markTaskCallFinished(sessionID, callID);
|
|
1486
1550
|
}
|
|
1487
1551
|
} catch (err) {
|
|
1488
1552
|
console.log(
|
package/package.json
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raindrop-ai/opencode-plugin",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"description": "Raindrop observability plugin for OpenCode — automatic session/event/span tracing",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/raindrop-ai/raindrop-js.git",
|
|
13
|
+
"directory": "packages/opencode-plugin"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://github.com/raindrop-ai/raindrop-js/tree/main/packages/opencode-plugin#readme",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/raindrop-ai/raindrop-js/issues"
|
|
18
|
+
},
|
|
9
19
|
"exports": {
|
|
10
20
|
".": {
|
|
11
21
|
"types": "./dist/index.d.ts",
|
|
@@ -17,12 +27,6 @@
|
|
|
17
27
|
"files": [
|
|
18
28
|
"dist/**"
|
|
19
29
|
],
|
|
20
|
-
"scripts": {
|
|
21
|
-
"build": "tsup",
|
|
22
|
-
"dev": "tsup --watch",
|
|
23
|
-
"clean": "rm -rf dist",
|
|
24
|
-
"test": "cd tests && pnpm test"
|
|
25
|
-
},
|
|
26
30
|
"peerDependencies": {
|
|
27
31
|
"@opencode-ai/plugin": ">=1.3.0",
|
|
28
32
|
"@opencode-ai/sdk": ">=1.3.0"
|
|
@@ -33,12 +37,12 @@
|
|
|
33
37
|
}
|
|
34
38
|
},
|
|
35
39
|
"devDependencies": {
|
|
36
|
-
"@raindrop-ai/core": "workspace:*",
|
|
37
40
|
"@opencode-ai/plugin": "^1.3.3",
|
|
38
41
|
"@opencode-ai/sdk": "^1.3.3",
|
|
39
42
|
"@types/node": "^20.11.17",
|
|
40
43
|
"tsup": "^8.4.0",
|
|
41
|
-
"typescript": "^5.3.3"
|
|
44
|
+
"typescript": "^5.3.3",
|
|
45
|
+
"@raindrop-ai/core": "0.0.1"
|
|
42
46
|
},
|
|
43
47
|
"tsup": {
|
|
44
48
|
"entry": [
|
|
@@ -58,5 +62,11 @@
|
|
|
58
62
|
},
|
|
59
63
|
"publishConfig": {
|
|
60
64
|
"access": "public"
|
|
65
|
+
},
|
|
66
|
+
"scripts": {
|
|
67
|
+
"build": "tsup",
|
|
68
|
+
"dev": "tsup --watch",
|
|
69
|
+
"clean": "rm -rf dist",
|
|
70
|
+
"test": "cd tests && pnpm test"
|
|
61
71
|
}
|
|
62
|
-
}
|
|
72
|
+
}
|