opencode-mlflow-plugin 1.0.0
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 +16 -0
- package/README.md +135 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +174 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
AGPL-3.0 License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MunhozThiago
|
|
4
|
+
|
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
|
6
|
+
it under the terms of the GNU Affero General Public License as published
|
|
7
|
+
by the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
(at your option) any later version.
|
|
9
|
+
|
|
10
|
+
This program is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
GNU Affero General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU Affero General Public License
|
|
16
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
package/README.md
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# opencode-mlflow-plugin
|
|
2
|
+
|
|
3
|
+
MLflow plugin for [opencode](https://opencode.ai) - tracks sessions and tool executions in your local MLflow server.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Automatically tracks each opencode session as an MLflow run
|
|
8
|
+
- Logs tool execution counts and errors
|
|
9
|
+
- Tracks session duration and message counts
|
|
10
|
+
- Optional detailed logging of tool inputs/outputs
|
|
11
|
+
- Connects to your local MLflow tracking server
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
### Via npm (recommended)
|
|
16
|
+
|
|
17
|
+
Add to your `opencode.json`:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"plugin": ["opencode-mlflow-plugin"]
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Local development
|
|
26
|
+
|
|
27
|
+
1. Clone this repository
|
|
28
|
+
2. Install dependencies:
|
|
29
|
+
```bash
|
|
30
|
+
npm install
|
|
31
|
+
```
|
|
32
|
+
3. Build the plugin:
|
|
33
|
+
```bash
|
|
34
|
+
npm run build
|
|
35
|
+
```
|
|
36
|
+
4. Reference locally in `opencode.json`:
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"plugin": ["./path/to/opencode-mlflow-plugin"]
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Configuration
|
|
44
|
+
|
|
45
|
+
### Prerequisites
|
|
46
|
+
|
|
47
|
+
1. Install MLflow:
|
|
48
|
+
```bash
|
|
49
|
+
pip install mlflow
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
2. Start the MLflow tracking server:
|
|
53
|
+
```bash
|
|
54
|
+
mlflow ui
|
|
55
|
+
```
|
|
56
|
+
This starts the UI at http://localhost:5000
|
|
57
|
+
|
|
58
|
+
### Plugin Options
|
|
59
|
+
|
|
60
|
+
Configure the plugin in `opencode.json`:
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"plugin": [
|
|
65
|
+
["opencode-mlflow-plugin", {
|
|
66
|
+
"trackingUri": "http://localhost:5000",
|
|
67
|
+
"experimentName": "opencode-sessions",
|
|
68
|
+
"logToolDetails": false
|
|
69
|
+
}]
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
| Option | Type | Default | Description |
|
|
75
|
+
|--------|------|---------|-------------|
|
|
76
|
+
| `trackingUri` | string | `http://localhost:5000` | MLflow tracking server URL |
|
|
77
|
+
| `experimentName` | string | `opencode-sessions` | Name of the MLflow experiment |
|
|
78
|
+
| `logToolDetails` | boolean | `false` | Log individual tool execution counts |
|
|
79
|
+
|
|
80
|
+
## What Gets Tracked
|
|
81
|
+
|
|
82
|
+
Each opencode session creates an MLflow run with:
|
|
83
|
+
|
|
84
|
+
### Parameters
|
|
85
|
+
- `session_id`: Unique identifier for the opencode session
|
|
86
|
+
|
|
87
|
+
### Metrics
|
|
88
|
+
- `tool_count`: Number of tool executions
|
|
89
|
+
- `message_count`: Number of chat messages
|
|
90
|
+
- `error_count`: Number of failed tool executions
|
|
91
|
+
- `duration_ms`: Session duration in milliseconds
|
|
92
|
+
- `final_tool_count`: Total tools executed
|
|
93
|
+
- `final_message_count`: Total messages
|
|
94
|
+
- `final_error_count`: Total errors
|
|
95
|
+
|
|
96
|
+
### Tags
|
|
97
|
+
- `opencode.session_id`: Session identifier
|
|
98
|
+
- `opencode.plugin_version`: Plugin version
|
|
99
|
+
|
|
100
|
+
## Viewing Results
|
|
101
|
+
|
|
102
|
+
1. Start MLflow UI:
|
|
103
|
+
```bash
|
|
104
|
+
mlflow ui
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
2. Open http://localhost:5000 in your browser
|
|
108
|
+
|
|
109
|
+
3. Select the "opencode-sessions" experiment
|
|
110
|
+
|
|
111
|
+
4. Click on any run to see metrics, parameters, and tags
|
|
112
|
+
|
|
113
|
+
## Development
|
|
114
|
+
|
|
115
|
+
### Build
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
npm run build
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Watch mode
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
npm run dev
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Publish to npm
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
npm publish
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## License
|
|
134
|
+
|
|
135
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAsB,MAAM,qBAAqB,CAAC;AAiEtE,QAAA,MAAM,MAAM,EAAE,MAuMb,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
const DEFAULT_OPTIONS = {
|
|
2
|
+
trackingUri: "http://localhost:5000",
|
|
3
|
+
experimentName: "opencode-sessions",
|
|
4
|
+
logToolDetails: false,
|
|
5
|
+
};
|
|
6
|
+
async function mlflowRequest(trackingUri, endpoint, method = "GET", body) {
|
|
7
|
+
const url = `${trackingUri}/api/2.0/mlflow${endpoint}`;
|
|
8
|
+
const headers = {
|
|
9
|
+
"Content-Type": "application/json",
|
|
10
|
+
Accept: "application/json",
|
|
11
|
+
};
|
|
12
|
+
const controller = new AbortController();
|
|
13
|
+
const timeout = setTimeout(() => controller.abort(), 5000);
|
|
14
|
+
try {
|
|
15
|
+
const options = { method, headers, signal: controller.signal };
|
|
16
|
+
if (body && method !== "GET") {
|
|
17
|
+
options.body = JSON.stringify(body);
|
|
18
|
+
}
|
|
19
|
+
const response = await fetch(url, options);
|
|
20
|
+
if (!response.ok) {
|
|
21
|
+
const text = await response.text();
|
|
22
|
+
throw new Error(`MLflow API error: ${response.status} ${response.statusText} - ${text}`);
|
|
23
|
+
}
|
|
24
|
+
return response.json();
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
clearTimeout(timeout);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const plugin = async (input, options) => {
|
|
31
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
32
|
+
const sessions = new Map();
|
|
33
|
+
let experimentId = null;
|
|
34
|
+
async function ensureExperiment() {
|
|
35
|
+
if (experimentId)
|
|
36
|
+
return experimentId;
|
|
37
|
+
const data = await mlflowRequest(opts.trackingUri, "/experiments/search", "POST", { max_results: 100 });
|
|
38
|
+
const existing = data.experiments?.find((e) => e.name === opts.experimentName);
|
|
39
|
+
if (existing) {
|
|
40
|
+
experimentId = existing.experiment_id;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const result = await mlflowRequest(opts.trackingUri, "/experiments/create", "POST", { name: opts.experimentName, artifact_location: "" });
|
|
44
|
+
experimentId = result.experiment_id;
|
|
45
|
+
}
|
|
46
|
+
return experimentId;
|
|
47
|
+
}
|
|
48
|
+
async function startRun(sessionId) {
|
|
49
|
+
const expId = await ensureExperiment();
|
|
50
|
+
const result = await mlflowRequest(opts.trackingUri, "/runs/create", "POST", {
|
|
51
|
+
experiment_id: expId,
|
|
52
|
+
user_id: "opencode",
|
|
53
|
+
start_time: Date.now(),
|
|
54
|
+
tags: [
|
|
55
|
+
{ key: "opencode.session_id", value: sessionId },
|
|
56
|
+
{ key: "opencode.plugin_version", value: "0.1.0" },
|
|
57
|
+
],
|
|
58
|
+
});
|
|
59
|
+
return result.run?.info?.run_id || "";
|
|
60
|
+
}
|
|
61
|
+
async function endRun(runId, status = "FINISHED") {
|
|
62
|
+
await mlflowRequest(opts.trackingUri, "/runs/update", "POST", {
|
|
63
|
+
run_id: runId,
|
|
64
|
+
status,
|
|
65
|
+
end_time: Date.now(),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
async function logMetric(runId, key, value) {
|
|
69
|
+
await mlflowRequest(opts.trackingUri, "/runs/log-metric", "POST", {
|
|
70
|
+
run_id: runId,
|
|
71
|
+
key,
|
|
72
|
+
value,
|
|
73
|
+
timestamp: Date.now(),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
async function logParam(runId, key, value) {
|
|
77
|
+
await mlflowRequest(opts.trackingUri, "/runs/log-parameter", "POST", {
|
|
78
|
+
run_id: runId,
|
|
79
|
+
key,
|
|
80
|
+
value,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
async function logTag(runId, key, value) {
|
|
84
|
+
await mlflowRequest(opts.trackingUri, "/runs/set-tag", "POST", {
|
|
85
|
+
run_id: runId,
|
|
86
|
+
key,
|
|
87
|
+
value,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
async function getOrCreateSession(sessionId) {
|
|
91
|
+
let session = sessions.get(sessionId);
|
|
92
|
+
if (!session) {
|
|
93
|
+
const runId = await startRun(sessionId);
|
|
94
|
+
session = {
|
|
95
|
+
runId,
|
|
96
|
+
startTime: Date.now(),
|
|
97
|
+
toolCount: 0,
|
|
98
|
+
messageCount: 0,
|
|
99
|
+
errors: 0,
|
|
100
|
+
toolTimings: new Map(),
|
|
101
|
+
};
|
|
102
|
+
sessions.set(sessionId, session);
|
|
103
|
+
await logParam(runId, "session_id", sessionId);
|
|
104
|
+
}
|
|
105
|
+
return session;
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
config: async () => { },
|
|
109
|
+
dispose: async () => {
|
|
110
|
+
for (const [sessionId, session] of sessions) {
|
|
111
|
+
await endRun(session.runId, "INTERRUPTED");
|
|
112
|
+
sessions.delete(sessionId);
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
"chat.message": async (input) => {
|
|
116
|
+
const session = await getOrCreateSession(input.sessionID);
|
|
117
|
+
session.messageCount++;
|
|
118
|
+
await logMetric(session.runId, "message_count", session.messageCount);
|
|
119
|
+
if (input.agent) {
|
|
120
|
+
await logTag(session.runId, "agent", input.agent);
|
|
121
|
+
}
|
|
122
|
+
if (input.model) {
|
|
123
|
+
await logTag(session.runId, "provider_id", input.model.providerID);
|
|
124
|
+
await logTag(session.runId, "model_id", input.model.modelID);
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"tool.execute.before": async (input) => {
|
|
128
|
+
const session = await getOrCreateSession(input.sessionID);
|
|
129
|
+
session.toolCount++;
|
|
130
|
+
session.toolTimings.set(input.callID, Date.now());
|
|
131
|
+
await logMetric(session.runId, "tool_count", session.toolCount);
|
|
132
|
+
if (opts.logToolDetails) {
|
|
133
|
+
const toolKey = `tool_${input.tool}_count`;
|
|
134
|
+
await logMetric(session.runId, toolKey, 1);
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"tool.execute.after": async (input, output) => {
|
|
138
|
+
const session = sessions.get(input.sessionID);
|
|
139
|
+
if (!session)
|
|
140
|
+
return;
|
|
141
|
+
const startTime = session.toolTimings.get(input.callID);
|
|
142
|
+
if (startTime) {
|
|
143
|
+
const duration = Date.now() - startTime;
|
|
144
|
+
await logMetric(session.runId, `tool_${input.tool}_duration_ms`, duration);
|
|
145
|
+
session.toolTimings.delete(input.callID);
|
|
146
|
+
}
|
|
147
|
+
if (output.metadata?.error || (output.output && output.output.includes("Error"))) {
|
|
148
|
+
session.errors++;
|
|
149
|
+
await logMetric(session.runId, "error_count", session.errors);
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
event: async (input) => {
|
|
153
|
+
const evt = input.event;
|
|
154
|
+
const sessionId = evt.sessionID || evt.sessionId;
|
|
155
|
+
if (!sessionId)
|
|
156
|
+
return;
|
|
157
|
+
const session = sessions.get(sessionId);
|
|
158
|
+
if (!session)
|
|
159
|
+
return;
|
|
160
|
+
if (evt.type === "session.end" || evt.type === "session.interrupt") {
|
|
161
|
+
const duration = Date.now() - session.startTime;
|
|
162
|
+
await logMetric(session.runId, "duration_ms", duration);
|
|
163
|
+
await logMetric(session.runId, "final_tool_count", session.toolCount);
|
|
164
|
+
await logMetric(session.runId, "final_message_count", session.messageCount);
|
|
165
|
+
await logMetric(session.runId, "final_error_count", session.errors);
|
|
166
|
+
const status = evt.type === "session.interrupt" ? "INTERRUPTED" : "FINISHED";
|
|
167
|
+
await endRun(session.runId, status);
|
|
168
|
+
sessions.delete(sessionId);
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
};
|
|
173
|
+
export default plugin;
|
|
174
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "opencode-mlflow-plugin",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MLflow plugin for opencode - tracks sessions, tool executions, and metrics in your local MLflow server",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"typecheck": "tsc --noEmit",
|
|
17
|
+
"dev": "tsc --watch",
|
|
18
|
+
"prepublishOnly": "npm run build"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"README.md",
|
|
23
|
+
"LICENSE"
|
|
24
|
+
],
|
|
25
|
+
"keywords": [
|
|
26
|
+
"opencode",
|
|
27
|
+
"opencode-plugin",
|
|
28
|
+
"mlflow",
|
|
29
|
+
"experiment-tracking",
|
|
30
|
+
"metrics",
|
|
31
|
+
"ai",
|
|
32
|
+
"machine-learning",
|
|
33
|
+
"tracking"
|
|
34
|
+
],
|
|
35
|
+
"author": "MunhozThiago",
|
|
36
|
+
"license": "AGPL-3.0",
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"@opencode-ai/plugin": "*"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@opencode-ai/plugin": "latest",
|
|
42
|
+
"typescript": "^5.0.0"
|
|
43
|
+
},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "https://github.com/MunhozThiago/opencode-mlflow-plugin"
|
|
50
|
+
},
|
|
51
|
+
"opencode": {
|
|
52
|
+
"name": "MLflow Tracker",
|
|
53
|
+
"description": "Tracks opencode sessions and tool executions in MLflow",
|
|
54
|
+
"minVersion": "0.1.0"
|
|
55
|
+
}
|
|
56
|
+
}
|