@tonyclaw/agent-inspector 2.1.6 → 2.1.8
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/.output/cli.js +274 -140
- package/.output/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-Djazxhew.js → CompareDrawer-CHkT7kun.js} +1 -1
- package/.output/public/assets/{ProxyViewerContainer-BC-z9RPh.js → ProxyViewerContainer-BiZ2_tMC.js} +36 -36
- package/.output/public/assets/{ReplayDialog-BaD4R6ac.js → ReplayDialog-C85cakjx.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-w6uGdqYp.js → RequestAnatomy-Dn_pMMoX.js} +1 -1
- package/.output/public/assets/{ResponseView-VPed-Yif.js → ResponseView-DzcxCUBf.js} +1 -1
- package/.output/public/assets/{StreamingChunkSequence-CPB8FgHI.js → StreamingChunkSequence-BamtvkgZ.js} +1 -1
- package/.output/public/assets/_sessionId-xBBbFH1M.js +1 -0
- package/.output/public/assets/index-6udjwQO1.js +1 -0
- package/.output/public/assets/{main-CIV3Chb5.js → main-Dc2qVWpb.js} +2 -2
- package/.output/server/{_sessionId-CIXQGim9.mjs → _sessionId-BnimGger.mjs} +3 -3
- package/.output/server/_ssr/{CompareDrawer-_uFgjkB2.mjs → CompareDrawer-CwVFykVF.mjs} +3 -3
- package/.output/server/_ssr/{ProxyViewerContainer-D8YjQDNj.mjs → ProxyViewerContainer-X3S2TWBJ.mjs} +236 -136
- package/.output/server/_ssr/{ReplayDialog-CFwKM7jc.mjs → ReplayDialog-BxC12XUj.mjs} +4 -4
- package/.output/server/_ssr/{RequestAnatomy-2Vr84GxT.mjs → RequestAnatomy-CWWS8Qh7.mjs} +3 -3
- package/.output/server/_ssr/{ResponseView-CSBWBHRJ.mjs → ResponseView-BewErHF-.mjs} +3 -3
- package/.output/server/_ssr/{StreamingChunkSequence-Dr4JApqs.mjs → StreamingChunkSequence-BlmCVryW.mjs} +3 -3
- package/.output/server/_ssr/{index-WnsY1fh_.mjs → index-5qbGuoFX.mjs} +3 -3
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-sy38X5AX.mjs → router-s78S54MU.mjs} +554 -124
- package/.output/server/{_tanstack-start-manifest_v-Dde-eACV.mjs → _tanstack-start-manifest_v-DTxpr3KE.mjs} +1 -1
- package/.output/server/index.mjs +61 -61
- package/README.md +10 -6
- package/package.json +1 -1
- package/src/cli/detect-tools.ts +2 -1
- package/src/cli/onboard.ts +334 -167
- package/src/components/groups/GroupsDialog.tsx +9 -4
- package/src/components/providers/SettingsDialog.tsx +67 -0
- package/src/components/proxy-viewer/ConversationGroup.tsx +28 -0
- package/src/components/proxy-viewer/ConversationHeader.tsx +34 -0
- package/src/components/proxy-viewer/LogEntryHeader.tsx +3 -12
- package/src/mcp/server.ts +18 -4
- package/src/proxy/sessionArchive.ts +410 -0
- package/src/proxy/store.ts +121 -6
- package/src/routes/api/logs.ts +2 -0
- package/src/routes/api/sessions.ts +2 -2
- package/.output/public/assets/_sessionId-mnr0O0Ri.js +0 -1
- package/.output/public/assets/index-DH1DjJOl.js +0 -1
|
@@ -2,17 +2,17 @@ import { c as createRouter, a as createRootRoute, b as createFileRoute, l as laz
|
|
|
2
2
|
import { j as jsxRuntimeExports } from "../_libs/react.mjs";
|
|
3
3
|
import { S as SWRConfig } from "../_libs/swr.mjs";
|
|
4
4
|
import { existsSync, readFileSync, mkdirSync, writeFileSync, renameSync, copyFileSync, unlinkSync, createReadStream, readdirSync, statSync, cpSync, rmSync, createWriteStream } from "node:fs";
|
|
5
|
-
import fs, { mkdir, appendFile, readFile, writeFile, readdir, open, stat, unlink, rename } from "node:fs/promises";
|
|
5
|
+
import fs, { mkdir, appendFile, readFile, writeFile, readdir, open, stat, unlink, rm, rename } from "node:fs/promises";
|
|
6
6
|
import { createInterface } from "node:readline";
|
|
7
7
|
import { Buffer } from "node:buffer";
|
|
8
|
-
import path, { basename, join,
|
|
8
|
+
import path, { basename, join, dirname, isAbsolute, resolve, relative } from "node:path";
|
|
9
|
+
import { randomUUID as randomUUID$1, createHash } from "node:crypto";
|
|
9
10
|
import { execFile, exec, spawn } from "node:child_process";
|
|
10
11
|
import { fileURLToPath } from "node:url";
|
|
11
12
|
import { C as Conf } from "../_libs/conf.mjs";
|
|
12
13
|
import { randomUUID } from "crypto";
|
|
13
14
|
import { promisify } from "node:util";
|
|
14
15
|
import { Worker } from "node:worker_threads";
|
|
15
|
-
import { randomUUID as randomUUID$1, createHash } from "node:crypto";
|
|
16
16
|
import { M as McpServer, W as WebStandardStreamableHTTPServerTransport, R as ResourceTemplate } from "../_libs/modelcontextprotocol__server.mjs";
|
|
17
17
|
import { J as JSZip } from "../_libs/jszip.mjs";
|
|
18
18
|
import { homedir } from "node:os";
|
|
@@ -108,7 +108,7 @@ function RootDocument({ children }) {
|
|
|
108
108
|
] })
|
|
109
109
|
] });
|
|
110
110
|
}
|
|
111
|
-
const $$splitComponentImporter$1 = () => import("./index-
|
|
111
|
+
const $$splitComponentImporter$1 = () => import("./index-5qbGuoFX.mjs");
|
|
112
112
|
const Route$C = createFileRoute("/")({
|
|
113
113
|
component: lazyRouteComponent($$splitComponentImporter$1, "component")
|
|
114
114
|
});
|
|
@@ -151,7 +151,7 @@ function decodeSessionIdFromPath(encoded) {
|
|
|
151
151
|
function getSessionPath(sessionId) {
|
|
152
152
|
return `/session/${encodeSessionIdForPath(sessionId)}`;
|
|
153
153
|
}
|
|
154
|
-
const $$splitComponentImporter = () => import("../_sessionId-
|
|
154
|
+
const $$splitComponentImporter = () => import("../_sessionId-BnimGger.mjs");
|
|
155
155
|
const Route$B = createFileRoute("/session/$sessionId")({
|
|
156
156
|
component: lazyRouteComponent($$splitComponentImporter, "component"),
|
|
157
157
|
parseParams: (params) => ({
|
|
@@ -865,9 +865,9 @@ function readChunks(path2) {
|
|
|
865
865
|
}
|
|
866
866
|
}
|
|
867
867
|
const SQLITE_INDEX_FILE = "inspector.sqlite";
|
|
868
|
-
const SQLITE_PACKAGE_NAME = "better-sqlite3";
|
|
869
|
-
const BUN_SQLITE_MODULE_NAME = "bun:sqlite";
|
|
870
|
-
const CREATE_SCHEMA_SQL = `
|
|
868
|
+
const SQLITE_PACKAGE_NAME$1 = "better-sqlite3";
|
|
869
|
+
const BUN_SQLITE_MODULE_NAME$1 = "bun:sqlite";
|
|
870
|
+
const CREATE_SCHEMA_SQL$1 = `
|
|
871
871
|
CREATE TABLE IF NOT EXISTS log_index (
|
|
872
872
|
id INTEGER PRIMARY KEY,
|
|
873
873
|
file TEXT NOT NULL,
|
|
@@ -908,7 +908,7 @@ CREATE INDEX IF NOT EXISTS idx_log_index_session_id_id ON log_index(session_id,
|
|
|
908
908
|
CREATE INDEX IF NOT EXISTS idx_log_index_model_id ON log_index(model, id);
|
|
909
909
|
CREATE INDEX IF NOT EXISTS idx_log_index_timestamp ON log_index(timestamp);
|
|
910
910
|
`;
|
|
911
|
-
const UPSERT_SQL = `
|
|
911
|
+
const UPSERT_SQL$1 = `
|
|
912
912
|
INSERT INTO log_index (
|
|
913
913
|
id,
|
|
914
914
|
file,
|
|
@@ -985,7 +985,7 @@ ON CONFLICT(id) DO UPDATE SET
|
|
|
985
985
|
let sqliteStatePromise = null;
|
|
986
986
|
let sqliteStatePath = null;
|
|
987
987
|
let activeDb = null;
|
|
988
|
-
let didLogUnavailable = false;
|
|
988
|
+
let didLogUnavailable$1 = false;
|
|
989
989
|
function isSqliteLogIndexEnabled() {
|
|
990
990
|
const configured = process.env["AGENT_INSPECTOR_SQLITE_INDEX"];
|
|
991
991
|
if (configured === "1") return true;
|
|
@@ -995,13 +995,13 @@ function isSqliteLogIndexEnabled() {
|
|
|
995
995
|
function getSqlitePath() {
|
|
996
996
|
return join(resolveLogDir(), SQLITE_INDEX_FILE);
|
|
997
997
|
}
|
|
998
|
-
function objectFromUnknown(value) {
|
|
998
|
+
function objectFromUnknown$1(value) {
|
|
999
999
|
if (value === null) return null;
|
|
1000
1000
|
if (typeof value === "object" || typeof value === "function") return value;
|
|
1001
1001
|
return null;
|
|
1002
1002
|
}
|
|
1003
|
-
function readProperty$
|
|
1004
|
-
let current = objectFromUnknown(value);
|
|
1003
|
+
function readProperty$2(value, name) {
|
|
1004
|
+
let current = objectFromUnknown$1(value);
|
|
1005
1005
|
while (current !== null) {
|
|
1006
1006
|
const desc = Object.getOwnPropertyDescriptor(current, name);
|
|
1007
1007
|
if (desc !== void 0) {
|
|
@@ -1009,16 +1009,16 @@ function readProperty$1(value, name) {
|
|
|
1009
1009
|
return propertyValue;
|
|
1010
1010
|
}
|
|
1011
1011
|
const nextPrototype = Object.getPrototypeOf(current);
|
|
1012
|
-
current = objectFromUnknown(nextPrototype);
|
|
1012
|
+
current = objectFromUnknown$1(nextPrototype);
|
|
1013
1013
|
}
|
|
1014
1014
|
return void 0;
|
|
1015
1015
|
}
|
|
1016
|
-
function readFunction(value, name) {
|
|
1017
|
-
const property = readProperty$
|
|
1016
|
+
function readFunction$1(value, name) {
|
|
1017
|
+
const property = readProperty$2(value, name);
|
|
1018
1018
|
return typeof property === "function" ? property : null;
|
|
1019
1019
|
}
|
|
1020
|
-
function callMethod(target, methodName, args) {
|
|
1021
|
-
const method = readFunction(target, methodName);
|
|
1020
|
+
function callMethod$1(target, methodName, args) {
|
|
1021
|
+
const method = readFunction$1(target, methodName);
|
|
1022
1022
|
if (method === null) return void 0;
|
|
1023
1023
|
try {
|
|
1024
1024
|
return Reflect.apply(method, target, [...args]);
|
|
@@ -1027,48 +1027,48 @@ function callMethod(target, methodName, args) {
|
|
|
1027
1027
|
return void 0;
|
|
1028
1028
|
}
|
|
1029
1029
|
}
|
|
1030
|
-
function prepareStatement(db, sql) {
|
|
1031
|
-
return callMethod(db, "prepare", [sql]);
|
|
1030
|
+
function prepareStatement$1(db, sql) {
|
|
1031
|
+
return callMethod$1(db, "prepare", [sql]);
|
|
1032
1032
|
}
|
|
1033
|
-
function runPrepared(db, sql, params = []) {
|
|
1034
|
-
const statement = prepareStatement(db, sql);
|
|
1033
|
+
function runPrepared$1(db, sql, params = []) {
|
|
1034
|
+
const statement = prepareStatement$1(db, sql);
|
|
1035
1035
|
if (statement === void 0) return false;
|
|
1036
|
-
const result = callMethod(statement, "run", params);
|
|
1037
|
-
callMethod(statement, "finalize", []);
|
|
1036
|
+
const result = callMethod$1(statement, "run", params);
|
|
1037
|
+
callMethod$1(statement, "finalize", []);
|
|
1038
1038
|
return result !== void 0;
|
|
1039
1039
|
}
|
|
1040
1040
|
function getPrepared(db, sql, params = []) {
|
|
1041
|
-
const statement = prepareStatement(db, sql);
|
|
1041
|
+
const statement = prepareStatement$1(db, sql);
|
|
1042
1042
|
if (statement === void 0) return void 0;
|
|
1043
|
-
const result = callMethod(statement, "get", params);
|
|
1044
|
-
callMethod(statement, "finalize", []);
|
|
1043
|
+
const result = callMethod$1(statement, "get", params);
|
|
1044
|
+
callMethod$1(statement, "finalize", []);
|
|
1045
1045
|
return result;
|
|
1046
1046
|
}
|
|
1047
|
-
function allPrepared(db, sql, params = []) {
|
|
1048
|
-
const statement = prepareStatement(db, sql);
|
|
1047
|
+
function allPrepared$1(db, sql, params = []) {
|
|
1048
|
+
const statement = prepareStatement$1(db, sql);
|
|
1049
1049
|
if (statement === void 0) return null;
|
|
1050
|
-
const result = callMethod(statement, "all", params);
|
|
1051
|
-
callMethod(statement, "finalize", []);
|
|
1050
|
+
const result = callMethod$1(statement, "all", params);
|
|
1051
|
+
callMethod$1(statement, "finalize", []);
|
|
1052
1052
|
return Array.isArray(result) ? result : null;
|
|
1053
1053
|
}
|
|
1054
|
-
function execSql(db, sql) {
|
|
1055
|
-
const result = callMethod(db, "exec", [sql]);
|
|
1054
|
+
function execSql$1(db, sql) {
|
|
1055
|
+
const result = callMethod$1(db, "exec", [sql]);
|
|
1056
1056
|
return result !== void 0;
|
|
1057
1057
|
}
|
|
1058
|
-
function sqliteConstructorFromModule(moduleValue, exportName) {
|
|
1059
|
-
const exportedValue = readProperty$
|
|
1058
|
+
function sqliteConstructorFromModule$1(moduleValue, exportName) {
|
|
1059
|
+
const exportedValue = readProperty$2(moduleValue, exportName);
|
|
1060
1060
|
if (typeof exportedValue === "function") {
|
|
1061
1061
|
return (path2) => Reflect.construct(exportedValue, [path2]);
|
|
1062
1062
|
}
|
|
1063
1063
|
return null;
|
|
1064
1064
|
}
|
|
1065
|
-
async function loadSqliteModuleConstructor(moduleName, exportName) {
|
|
1065
|
+
async function loadSqliteModuleConstructor$1(moduleName, exportName) {
|
|
1066
1066
|
try {
|
|
1067
1067
|
const importedModule = await import(
|
|
1068
1068
|
/* @vite-ignore */
|
|
1069
1069
|
moduleName
|
|
1070
1070
|
);
|
|
1071
|
-
const exportedConstructor = sqliteConstructorFromModule(importedModule, exportName);
|
|
1071
|
+
const exportedConstructor = sqliteConstructorFromModule$1(importedModule, exportName);
|
|
1072
1072
|
if (exportedConstructor !== null) return { constructor: exportedConstructor, reason: null };
|
|
1073
1073
|
if (exportName === "default" && typeof importedModule === "function") {
|
|
1074
1074
|
return {
|
|
@@ -1081,27 +1081,27 @@ async function loadSqliteModuleConstructor(moduleName, exportName) {
|
|
|
1081
1081
|
return { constructor: null, reason: String(err) };
|
|
1082
1082
|
}
|
|
1083
1083
|
}
|
|
1084
|
-
async function loadSqliteConstructor() {
|
|
1084
|
+
async function loadSqliteConstructor$1() {
|
|
1085
1085
|
const bunRuntimeDesc = Object.getOwnPropertyDescriptor(process.versions, "bun");
|
|
1086
1086
|
if (bunRuntimeDesc !== void 0) {
|
|
1087
|
-
const bunSqlite2 = await loadSqliteModuleConstructor(BUN_SQLITE_MODULE_NAME, "Database");
|
|
1087
|
+
const bunSqlite2 = await loadSqliteModuleConstructor$1(BUN_SQLITE_MODULE_NAME$1, "Database");
|
|
1088
1088
|
if (bunSqlite2.constructor !== null) return bunSqlite2;
|
|
1089
|
-
const betterSqlite2 = await loadSqliteModuleConstructor(SQLITE_PACKAGE_NAME, "default");
|
|
1089
|
+
const betterSqlite2 = await loadSqliteModuleConstructor$1(SQLITE_PACKAGE_NAME$1, "default");
|
|
1090
1090
|
if (betterSqlite2.constructor !== null) return betterSqlite2;
|
|
1091
1091
|
const reason2 = [bunSqlite2.reason, betterSqlite2.reason].filter((item) => item !== null).join("; ");
|
|
1092
|
-
if (!didLogUnavailable) {
|
|
1093
|
-
didLogUnavailable = true;
|
|
1092
|
+
if (!didLogUnavailable$1) {
|
|
1093
|
+
didLogUnavailable$1 = true;
|
|
1094
1094
|
logger.warn("[sqliteLogIndex] Optional SQLite index unavailable:", reason2);
|
|
1095
1095
|
}
|
|
1096
1096
|
return { constructor: null, reason: reason2 };
|
|
1097
1097
|
}
|
|
1098
|
-
const betterSqlite = await loadSqliteModuleConstructor(SQLITE_PACKAGE_NAME, "default");
|
|
1098
|
+
const betterSqlite = await loadSqliteModuleConstructor$1(SQLITE_PACKAGE_NAME$1, "default");
|
|
1099
1099
|
if (betterSqlite.constructor !== null) return betterSqlite;
|
|
1100
|
-
const bunSqlite = await loadSqliteModuleConstructor(BUN_SQLITE_MODULE_NAME, "Database");
|
|
1100
|
+
const bunSqlite = await loadSqliteModuleConstructor$1(BUN_SQLITE_MODULE_NAME$1, "Database");
|
|
1101
1101
|
if (bunSqlite.constructor !== null) return bunSqlite;
|
|
1102
1102
|
const reason = [betterSqlite.reason, bunSqlite.reason].filter((item) => item !== null).join("; ");
|
|
1103
|
-
if (!didLogUnavailable) {
|
|
1104
|
-
didLogUnavailable = true;
|
|
1103
|
+
if (!didLogUnavailable$1) {
|
|
1104
|
+
didLogUnavailable$1 = true;
|
|
1105
1105
|
logger.warn("[sqliteLogIndex] Optional SQLite index unavailable:", reason);
|
|
1106
1106
|
}
|
|
1107
1107
|
return { constructor: null, reason };
|
|
@@ -1111,7 +1111,7 @@ async function initializeSqliteState() {
|
|
|
1111
1111
|
if (!isSqliteLogIndexEnabled()) {
|
|
1112
1112
|
return { status: "unavailable", path: path2, reason: "SQLite log index is disabled" };
|
|
1113
1113
|
}
|
|
1114
|
-
const sqliteConstructor = await loadSqliteConstructor();
|
|
1114
|
+
const sqliteConstructor = await loadSqliteConstructor$1();
|
|
1115
1115
|
if (sqliteConstructor.constructor === null) {
|
|
1116
1116
|
return {
|
|
1117
1117
|
status: "unavailable",
|
|
@@ -1122,9 +1122,9 @@ async function initializeSqliteState() {
|
|
|
1122
1122
|
try {
|
|
1123
1123
|
await mkdir(dirname(path2), { recursive: true });
|
|
1124
1124
|
const db = sqliteConstructor.constructor(path2);
|
|
1125
|
-
execSql(db, "PRAGMA journal_mode = WAL");
|
|
1126
|
-
execSql(db, "PRAGMA synchronous = NORMAL");
|
|
1127
|
-
if (!execSql(db, CREATE_SCHEMA_SQL)) {
|
|
1125
|
+
execSql$1(db, "PRAGMA journal_mode = WAL");
|
|
1126
|
+
execSql$1(db, "PRAGMA synchronous = NORMAL");
|
|
1127
|
+
if (!execSql$1(db, CREATE_SCHEMA_SQL$1)) {
|
|
1128
1128
|
return { status: "unavailable", path: path2, reason: "SQLite schema initialization failed" };
|
|
1129
1129
|
}
|
|
1130
1130
|
activeDb = db;
|
|
@@ -1147,7 +1147,7 @@ async function getSqliteState() {
|
|
|
1147
1147
|
}
|
|
1148
1148
|
function closeSqliteLogIndex() {
|
|
1149
1149
|
if (activeDb !== null) {
|
|
1150
|
-
callMethod(activeDb, "close", []);
|
|
1150
|
+
callMethod$1(activeDb, "close", []);
|
|
1151
1151
|
}
|
|
1152
1152
|
activeDb = null;
|
|
1153
1153
|
sqliteStatePromise = null;
|
|
@@ -1198,19 +1198,19 @@ function entryParams(entry) {
|
|
|
1198
1198
|
summary?.error ?? null
|
|
1199
1199
|
];
|
|
1200
1200
|
}
|
|
1201
|
-
function readNumber(row, name) {
|
|
1202
|
-
const value = readProperty$
|
|
1201
|
+
function readNumber$1(row, name) {
|
|
1202
|
+
const value = readProperty$2(row, name);
|
|
1203
1203
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
1204
1204
|
}
|
|
1205
|
-
function readString$
|
|
1206
|
-
const value = readProperty$
|
|
1205
|
+
function readString$2(row, name) {
|
|
1206
|
+
const value = readProperty$2(row, name);
|
|
1207
1207
|
return typeof value === "string" ? value : null;
|
|
1208
1208
|
}
|
|
1209
1209
|
function readBoolean(row, name) {
|
|
1210
|
-
return readNumber(row, name) === 1;
|
|
1210
|
+
return readNumber$1(row, name) === 1;
|
|
1211
1211
|
}
|
|
1212
1212
|
function readApiFormat(row) {
|
|
1213
|
-
const value = readString$
|
|
1213
|
+
const value = readString$2(row, "api_format");
|
|
1214
1214
|
switch (value) {
|
|
1215
1215
|
case "anthropic":
|
|
1216
1216
|
return "anthropic";
|
|
@@ -1224,7 +1224,7 @@ function readApiFormat(row) {
|
|
|
1224
1224
|
}
|
|
1225
1225
|
}
|
|
1226
1226
|
function readWarnings(row) {
|
|
1227
|
-
const value = readString$
|
|
1227
|
+
const value = readString$2(row, "warnings_json");
|
|
1228
1228
|
if (value === null) return void 0;
|
|
1229
1229
|
try {
|
|
1230
1230
|
const parsed = JSON.parse(value);
|
|
@@ -1240,47 +1240,47 @@ function readWarnings(row) {
|
|
|
1240
1240
|
}
|
|
1241
1241
|
}
|
|
1242
1242
|
function readRequiredNumber(row, name) {
|
|
1243
|
-
const value = readNumber(row, name);
|
|
1243
|
+
const value = readNumber$1(row, name);
|
|
1244
1244
|
return value === null || !Number.isInteger(value) ? null : value;
|
|
1245
1245
|
}
|
|
1246
1246
|
function summaryFromRow(row, id) {
|
|
1247
1247
|
return {
|
|
1248
1248
|
id,
|
|
1249
|
-
timestamp: readString$
|
|
1250
|
-
method: readString$
|
|
1251
|
-
path: readString$
|
|
1252
|
-
model: readString$
|
|
1253
|
-
sessionId: readString$
|
|
1254
|
-
responseStatus: readNumber(row, "response_status"),
|
|
1255
|
-
inputTokens: readNumber(row, "input_tokens"),
|
|
1256
|
-
outputTokens: readNumber(row, "output_tokens"),
|
|
1257
|
-
cacheCreationInputTokens: readNumber(row, "cache_creation_input_tokens"),
|
|
1258
|
-
cacheReadInputTokens: readNumber(row, "cache_read_input_tokens"),
|
|
1259
|
-
elapsedMs: readNumber(row, "elapsed_ms"),
|
|
1260
|
-
firstChunkMs: readNumber(row, "first_chunk_ms"),
|
|
1261
|
-
totalStreamMs: readNumber(row, "total_stream_ms"),
|
|
1262
|
-
tokensPerSecond: readNumber(row, "tokens_per_second"),
|
|
1249
|
+
timestamp: readString$2(row, "timestamp") ?? "",
|
|
1250
|
+
method: readString$2(row, "method") ?? "",
|
|
1251
|
+
path: readString$2(row, "path") ?? "",
|
|
1252
|
+
model: readString$2(row, "model"),
|
|
1253
|
+
sessionId: readString$2(row, "session_id"),
|
|
1254
|
+
responseStatus: readNumber$1(row, "response_status"),
|
|
1255
|
+
inputTokens: readNumber$1(row, "input_tokens"),
|
|
1256
|
+
outputTokens: readNumber$1(row, "output_tokens"),
|
|
1257
|
+
cacheCreationInputTokens: readNumber$1(row, "cache_creation_input_tokens"),
|
|
1258
|
+
cacheReadInputTokens: readNumber$1(row, "cache_read_input_tokens"),
|
|
1259
|
+
elapsedMs: readNumber$1(row, "elapsed_ms"),
|
|
1260
|
+
firstChunkMs: readNumber$1(row, "first_chunk_ms"),
|
|
1261
|
+
totalStreamMs: readNumber$1(row, "total_stream_ms"),
|
|
1262
|
+
tokensPerSecond: readNumber$1(row, "tokens_per_second"),
|
|
1263
1263
|
streaming: readBoolean(row, "streaming"),
|
|
1264
|
-
userAgent: readString$
|
|
1265
|
-
origin: readString$
|
|
1264
|
+
userAgent: readString$2(row, "user_agent"),
|
|
1265
|
+
origin: readString$2(row, "origin"),
|
|
1266
1266
|
apiFormat: readApiFormat(row),
|
|
1267
1267
|
isTest: readBoolean(row, "is_test"),
|
|
1268
|
-
replayOfLogId: readNumber(row, "replay_of_log_id"),
|
|
1269
|
-
providerName: readString$
|
|
1270
|
-
clientPort: readNumber(row, "client_port"),
|
|
1271
|
-
clientPid: readNumber(row, "client_pid"),
|
|
1272
|
-
clientCwd: readString$
|
|
1273
|
-
clientProjectFolder: readString$
|
|
1274
|
-
streamingChunksPath: readString$
|
|
1275
|
-
rawRequestBodyBytes: readNumber(row, "raw_request_body_bytes"),
|
|
1276
|
-
responseTextBytes: readNumber(row, "response_text_bytes"),
|
|
1268
|
+
replayOfLogId: readNumber$1(row, "replay_of_log_id"),
|
|
1269
|
+
providerName: readString$2(row, "provider_name"),
|
|
1270
|
+
clientPort: readNumber$1(row, "client_port"),
|
|
1271
|
+
clientPid: readNumber$1(row, "client_pid"),
|
|
1272
|
+
clientCwd: readString$2(row, "client_cwd"),
|
|
1273
|
+
clientProjectFolder: readString$2(row, "client_project_folder"),
|
|
1274
|
+
streamingChunksPath: readString$2(row, "streaming_chunks_path"),
|
|
1275
|
+
rawRequestBodyBytes: readNumber$1(row, "raw_request_body_bytes"),
|
|
1276
|
+
responseTextBytes: readNumber$1(row, "response_text_bytes"),
|
|
1277
1277
|
warnings: readWarnings(row),
|
|
1278
|
-
error: readString$
|
|
1278
|
+
error: readString$2(row, "error")
|
|
1279
1279
|
};
|
|
1280
1280
|
}
|
|
1281
1281
|
function entryFromRow(row) {
|
|
1282
1282
|
const id = readRequiredNumber(row, "id");
|
|
1283
|
-
const file = readString$
|
|
1283
|
+
const file = readString$2(row, "file");
|
|
1284
1284
|
const byteOffset = readRequiredNumber(row, "byte_offset");
|
|
1285
1285
|
const byteLength = readRequiredNumber(row, "byte_length");
|
|
1286
1286
|
if (id === null || file === null || byteOffset === null || byteLength === null) return null;
|
|
@@ -1289,8 +1289,8 @@ function entryFromRow(row) {
|
|
|
1289
1289
|
file,
|
|
1290
1290
|
byteOffset,
|
|
1291
1291
|
byteLength,
|
|
1292
|
-
sessionId: readString$
|
|
1293
|
-
model: readString$
|
|
1292
|
+
sessionId: readString$2(row, "session_id"),
|
|
1293
|
+
model: readString$2(row, "model"),
|
|
1294
1294
|
summary: summaryFromRow(row, id)
|
|
1295
1295
|
};
|
|
1296
1296
|
}
|
|
@@ -1298,30 +1298,30 @@ async function getSqliteLogIndexMaxId() {
|
|
|
1298
1298
|
const state = await getSqliteState();
|
|
1299
1299
|
if (state.status !== "ready") return null;
|
|
1300
1300
|
const row = getPrepared(state.db, "SELECT MAX(id) AS max_id FROM log_index");
|
|
1301
|
-
return readNumber(row, "max_id") ?? 0;
|
|
1301
|
+
return readNumber$1(row, "max_id") ?? 0;
|
|
1302
1302
|
}
|
|
1303
1303
|
async function upsertSqliteLogIndexEntry(entry) {
|
|
1304
1304
|
if (entry.summary === void 0) return false;
|
|
1305
1305
|
const state = await getSqliteState();
|
|
1306
1306
|
if (state.status !== "ready") return false;
|
|
1307
|
-
return runPrepared(state.db, UPSERT_SQL, entryParams(entry));
|
|
1307
|
+
return runPrepared$1(state.db, UPSERT_SQL$1, entryParams(entry));
|
|
1308
1308
|
}
|
|
1309
1309
|
async function syncSqliteLogIndexEntries(entries) {
|
|
1310
1310
|
const state = await getSqliteState();
|
|
1311
1311
|
if (state.status !== "ready") return false;
|
|
1312
1312
|
if (entries.length === 0) return true;
|
|
1313
|
-
if (!execSql(state.db, "BEGIN IMMEDIATE")) return false;
|
|
1313
|
+
if (!execSql$1(state.db, "BEGIN IMMEDIATE")) return false;
|
|
1314
1314
|
try {
|
|
1315
1315
|
for (const entry of entries) {
|
|
1316
1316
|
if (entry.summary === void 0) continue;
|
|
1317
|
-
if (!runPrepared(state.db, UPSERT_SQL, entryParams(entry))) {
|
|
1318
|
-
execSql(state.db, "ROLLBACK");
|
|
1317
|
+
if (!runPrepared$1(state.db, UPSERT_SQL$1, entryParams(entry))) {
|
|
1318
|
+
execSql$1(state.db, "ROLLBACK");
|
|
1319
1319
|
return false;
|
|
1320
1320
|
}
|
|
1321
1321
|
}
|
|
1322
|
-
return execSql(state.db, "COMMIT");
|
|
1322
|
+
return execSql$1(state.db, "COMMIT");
|
|
1323
1323
|
} catch (err) {
|
|
1324
|
-
execSql(state.db, "ROLLBACK");
|
|
1324
|
+
execSql$1(state.db, "ROLLBACK");
|
|
1325
1325
|
logger.warn("[sqliteLogIndex] Failed to sync SQLite index:", String(err));
|
|
1326
1326
|
return false;
|
|
1327
1327
|
}
|
|
@@ -1349,7 +1349,7 @@ async function listSqliteLogIndexEntries({
|
|
|
1349
1349
|
params.push(model);
|
|
1350
1350
|
}
|
|
1351
1351
|
const where = clauses.length === 0 ? "" : ` WHERE ${clauses.join(" AND ")}`;
|
|
1352
|
-
const rows = allPrepared(state.db, `SELECT * FROM log_index${where} ORDER BY id ASC`, params);
|
|
1352
|
+
const rows = allPrepared$1(state.db, `SELECT * FROM log_index${where} ORDER BY id ASC`, params);
|
|
1353
1353
|
if (rows === null) return null;
|
|
1354
1354
|
const entries = [];
|
|
1355
1355
|
for (const row of rows) {
|
|
@@ -1361,22 +1361,22 @@ async function listSqliteLogIndexEntries({
|
|
|
1361
1361
|
async function replaceSqliteLogIndexEntries(entries) {
|
|
1362
1362
|
const state = await getSqliteState();
|
|
1363
1363
|
if (state.status !== "ready") return false;
|
|
1364
|
-
if (!execSql(state.db, "BEGIN IMMEDIATE")) return false;
|
|
1364
|
+
if (!execSql$1(state.db, "BEGIN IMMEDIATE")) return false;
|
|
1365
1365
|
try {
|
|
1366
|
-
if (!runPrepared(state.db, "DELETE FROM log_index")) {
|
|
1367
|
-
execSql(state.db, "ROLLBACK");
|
|
1366
|
+
if (!runPrepared$1(state.db, "DELETE FROM log_index")) {
|
|
1367
|
+
execSql$1(state.db, "ROLLBACK");
|
|
1368
1368
|
return false;
|
|
1369
1369
|
}
|
|
1370
1370
|
for (const entry of entries) {
|
|
1371
1371
|
if (entry.summary === void 0) continue;
|
|
1372
|
-
if (!runPrepared(state.db, UPSERT_SQL, entryParams(entry))) {
|
|
1373
|
-
execSql(state.db, "ROLLBACK");
|
|
1372
|
+
if (!runPrepared$1(state.db, UPSERT_SQL$1, entryParams(entry))) {
|
|
1373
|
+
execSql$1(state.db, "ROLLBACK");
|
|
1374
1374
|
return false;
|
|
1375
1375
|
}
|
|
1376
1376
|
}
|
|
1377
|
-
return execSql(state.db, "COMMIT");
|
|
1377
|
+
return execSql$1(state.db, "COMMIT");
|
|
1378
1378
|
} catch (err) {
|
|
1379
|
-
execSql(state.db, "ROLLBACK");
|
|
1379
|
+
execSql$1(state.db, "ROLLBACK");
|
|
1380
1380
|
logger.warn("[sqliteLogIndex] Failed to replace SQLite index:", String(err));
|
|
1381
1381
|
return false;
|
|
1382
1382
|
}
|
|
@@ -1986,6 +1986,342 @@ function apiFormatForPath(path2) {
|
|
|
1986
1986
|
formatRegistry.registerPath(PATH_V1_MESSAGES, "anthropic");
|
|
1987
1987
|
formatRegistry.registerPath(PATH_V1_CHAT_COMPLETIONS, "openai");
|
|
1988
1988
|
formatRegistry.registerPath(PATH_CHAT_COMPLETIONS, "openai");
|
|
1989
|
+
const SESSION_ARCHIVE_DIR = "sessions";
|
|
1990
|
+
const SESSION_ARCHIVE_FILE = "session.sqlite";
|
|
1991
|
+
const SQLITE_PACKAGE_NAME = "better-sqlite3";
|
|
1992
|
+
const BUN_SQLITE_MODULE_NAME = "bun:sqlite";
|
|
1993
|
+
const CREATE_SCHEMA_SQL = `
|
|
1994
|
+
CREATE TABLE IF NOT EXISTS session_logs (
|
|
1995
|
+
id INTEGER PRIMARY KEY,
|
|
1996
|
+
session_id TEXT NOT NULL,
|
|
1997
|
+
log_json TEXT NOT NULL,
|
|
1998
|
+
updated_at TEXT NOT NULL
|
|
1999
|
+
);
|
|
2000
|
+
CREATE INDEX IF NOT EXISTS idx_session_logs_session_id_id ON session_logs(session_id, id);
|
|
2001
|
+
`;
|
|
2002
|
+
const UPSERT_SQL = `
|
|
2003
|
+
INSERT INTO session_logs (
|
|
2004
|
+
id,
|
|
2005
|
+
session_id,
|
|
2006
|
+
log_json,
|
|
2007
|
+
updated_at
|
|
2008
|
+
) VALUES (?, ?, ?, ?)
|
|
2009
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
2010
|
+
session_id = excluded.session_id,
|
|
2011
|
+
log_json = excluded.log_json,
|
|
2012
|
+
updated_at = excluded.updated_at
|
|
2013
|
+
`;
|
|
2014
|
+
let didLogUnavailable = false;
|
|
2015
|
+
function getSessionArchiveRoot() {
|
|
2016
|
+
return join(resolveLogDir(), SESSION_ARCHIVE_DIR);
|
|
2017
|
+
}
|
|
2018
|
+
function hashSessionId(sessionId) {
|
|
2019
|
+
return createHash("sha256").update(sessionId).digest("hex").slice(0, 16);
|
|
2020
|
+
}
|
|
2021
|
+
function sanitizeSessionPrefix(sessionId) {
|
|
2022
|
+
const trimmed = sessionId.trim();
|
|
2023
|
+
if (trimmed.length === 0) return "session";
|
|
2024
|
+
const normalized = trimmed.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
2025
|
+
if (normalized.length === 0) return "session";
|
|
2026
|
+
return normalized.slice(0, 48);
|
|
2027
|
+
}
|
|
2028
|
+
function sessionArchiveKey(sessionId) {
|
|
2029
|
+
return `${sanitizeSessionPrefix(sessionId)}--${hashSessionId(sessionId)}`;
|
|
2030
|
+
}
|
|
2031
|
+
function getSessionArchivePath(sessionId) {
|
|
2032
|
+
return join(getSessionArchiveRoot(), sessionArchiveKey(sessionId), SESSION_ARCHIVE_FILE);
|
|
2033
|
+
}
|
|
2034
|
+
function objectFromUnknown(value) {
|
|
2035
|
+
if (value === null) return null;
|
|
2036
|
+
if (typeof value === "object" || typeof value === "function") return value;
|
|
2037
|
+
return null;
|
|
2038
|
+
}
|
|
2039
|
+
function readProperty$1(value, name) {
|
|
2040
|
+
let current = objectFromUnknown(value);
|
|
2041
|
+
while (current !== null) {
|
|
2042
|
+
const desc = Object.getOwnPropertyDescriptor(current, name);
|
|
2043
|
+
if (desc !== void 0) {
|
|
2044
|
+
const propertyValue = Reflect.get(current, name);
|
|
2045
|
+
return propertyValue;
|
|
2046
|
+
}
|
|
2047
|
+
const nextPrototype = Object.getPrototypeOf(current);
|
|
2048
|
+
current = objectFromUnknown(nextPrototype);
|
|
2049
|
+
}
|
|
2050
|
+
return void 0;
|
|
2051
|
+
}
|
|
2052
|
+
function readFunction(value, name) {
|
|
2053
|
+
const property = readProperty$1(value, name);
|
|
2054
|
+
return typeof property === "function" ? property : null;
|
|
2055
|
+
}
|
|
2056
|
+
function callMethod(target, methodName, args) {
|
|
2057
|
+
const method = readFunction(target, methodName);
|
|
2058
|
+
if (method === null) return void 0;
|
|
2059
|
+
try {
|
|
2060
|
+
return Reflect.apply(method, target, [...args]);
|
|
2061
|
+
} catch (err) {
|
|
2062
|
+
logger.warn("[sessionArchive] SQLite method failed:", methodName, String(err));
|
|
2063
|
+
return void 0;
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
function prepareStatement(db, sql) {
|
|
2067
|
+
return callMethod(db, "prepare", [sql]);
|
|
2068
|
+
}
|
|
2069
|
+
function runPrepared(db, sql, params = []) {
|
|
2070
|
+
const statement = prepareStatement(db, sql);
|
|
2071
|
+
if (statement === void 0) return false;
|
|
2072
|
+
const result = callMethod(statement, "run", params);
|
|
2073
|
+
callMethod(statement, "finalize", []);
|
|
2074
|
+
return result !== void 0;
|
|
2075
|
+
}
|
|
2076
|
+
function allPrepared(db, sql, params = []) {
|
|
2077
|
+
const statement = prepareStatement(db, sql);
|
|
2078
|
+
if (statement === void 0) return [];
|
|
2079
|
+
const result = callMethod(statement, "all", params);
|
|
2080
|
+
callMethod(statement, "finalize", []);
|
|
2081
|
+
return Array.isArray(result) ? result : [];
|
|
2082
|
+
}
|
|
2083
|
+
function execSql(db, sql) {
|
|
2084
|
+
const result = callMethod(db, "exec", [sql]);
|
|
2085
|
+
return result !== void 0;
|
|
2086
|
+
}
|
|
2087
|
+
function closeDatabase(db) {
|
|
2088
|
+
callMethod(db, "close", []);
|
|
2089
|
+
}
|
|
2090
|
+
function sqliteConstructorFromModule(moduleValue, exportName) {
|
|
2091
|
+
const exportedValue = readProperty$1(moduleValue, exportName);
|
|
2092
|
+
if (typeof exportedValue === "function") {
|
|
2093
|
+
return (path2) => Reflect.construct(exportedValue, [path2]);
|
|
2094
|
+
}
|
|
2095
|
+
return null;
|
|
2096
|
+
}
|
|
2097
|
+
async function loadSqliteModuleConstructor(moduleName, exportName) {
|
|
2098
|
+
try {
|
|
2099
|
+
const importedModule = await import(
|
|
2100
|
+
/* @vite-ignore */
|
|
2101
|
+
moduleName
|
|
2102
|
+
);
|
|
2103
|
+
const exportedConstructor = sqliteConstructorFromModule(importedModule, exportName);
|
|
2104
|
+
if (exportedConstructor !== null) return { constructor: exportedConstructor, reason: null };
|
|
2105
|
+
if (exportName === "default" && typeof importedModule === "function") {
|
|
2106
|
+
return {
|
|
2107
|
+
constructor: (path2) => Reflect.construct(importedModule, [path2]),
|
|
2108
|
+
reason: null
|
|
2109
|
+
};
|
|
2110
|
+
}
|
|
2111
|
+
return { constructor: null, reason: `${moduleName} did not expose ${exportName}` };
|
|
2112
|
+
} catch (err) {
|
|
2113
|
+
return { constructor: null, reason: String(err) };
|
|
2114
|
+
}
|
|
2115
|
+
}
|
|
2116
|
+
async function loadSqliteConstructor() {
|
|
2117
|
+
const bunRuntimeDesc = Object.getOwnPropertyDescriptor(process.versions, "bun");
|
|
2118
|
+
if (bunRuntimeDesc !== void 0) {
|
|
2119
|
+
const bunSqlite2 = await loadSqliteModuleConstructor(BUN_SQLITE_MODULE_NAME, "Database");
|
|
2120
|
+
if (bunSqlite2.constructor !== null) return bunSqlite2;
|
|
2121
|
+
const betterSqlite2 = await loadSqliteModuleConstructor(SQLITE_PACKAGE_NAME, "default");
|
|
2122
|
+
if (betterSqlite2.constructor !== null) return betterSqlite2;
|
|
2123
|
+
return {
|
|
2124
|
+
constructor: null,
|
|
2125
|
+
reason: [bunSqlite2.reason, betterSqlite2.reason].filter((item) => item !== null).join("; ")
|
|
2126
|
+
};
|
|
2127
|
+
}
|
|
2128
|
+
const betterSqlite = await loadSqliteModuleConstructor(SQLITE_PACKAGE_NAME, "default");
|
|
2129
|
+
if (betterSqlite.constructor !== null) return betterSqlite;
|
|
2130
|
+
const bunSqlite = await loadSqliteModuleConstructor(BUN_SQLITE_MODULE_NAME, "Database");
|
|
2131
|
+
if (bunSqlite.constructor !== null) return bunSqlite;
|
|
2132
|
+
return {
|
|
2133
|
+
constructor: null,
|
|
2134
|
+
reason: [betterSqlite.reason, bunSqlite.reason].filter((item) => item !== null).join("; ")
|
|
2135
|
+
};
|
|
2136
|
+
}
|
|
2137
|
+
function logUnavailableOnce(reason) {
|
|
2138
|
+
if (didLogUnavailable) return;
|
|
2139
|
+
didLogUnavailable = true;
|
|
2140
|
+
logger.warn("[sessionArchive] Optional session archive unavailable:", reason);
|
|
2141
|
+
}
|
|
2142
|
+
async function openSessionArchiveDb(filePath, create) {
|
|
2143
|
+
if (!create && !existsSync(filePath)) return null;
|
|
2144
|
+
const sqliteConstructor = await loadSqliteConstructor();
|
|
2145
|
+
if (sqliteConstructor.constructor === null) {
|
|
2146
|
+
logUnavailableOnce(sqliteConstructor.reason ?? "SQLite runtime is not available");
|
|
2147
|
+
return null;
|
|
2148
|
+
}
|
|
2149
|
+
try {
|
|
2150
|
+
if (create) await mkdir(dirname(filePath), { recursive: true });
|
|
2151
|
+
const db = sqliteConstructor.constructor(filePath);
|
|
2152
|
+
execSql(db, "PRAGMA journal_mode = WAL");
|
|
2153
|
+
execSql(db, "PRAGMA synchronous = NORMAL");
|
|
2154
|
+
if (!execSql(db, CREATE_SCHEMA_SQL)) {
|
|
2155
|
+
closeDatabase(db);
|
|
2156
|
+
logger.warn("[sessionArchive] Failed to initialize schema:", filePath);
|
|
2157
|
+
return null;
|
|
2158
|
+
}
|
|
2159
|
+
return db;
|
|
2160
|
+
} catch (err) {
|
|
2161
|
+
logger.warn("[sessionArchive] Failed to open session archive:", filePath, String(err));
|
|
2162
|
+
return null;
|
|
2163
|
+
}
|
|
2164
|
+
}
|
|
2165
|
+
async function archiveSessionLog(log) {
|
|
2166
|
+
const sessionId = log.sessionId;
|
|
2167
|
+
if (sessionId === null || sessionId.trim().length === 0) return false;
|
|
2168
|
+
const db = await openSessionArchiveDb(getSessionArchivePath(sessionId), true);
|
|
2169
|
+
if (db === null) return false;
|
|
2170
|
+
try {
|
|
2171
|
+
return runPrepared(db, UPSERT_SQL, [
|
|
2172
|
+
log.id,
|
|
2173
|
+
sessionId,
|
|
2174
|
+
JSON.stringify(log),
|
|
2175
|
+
(/* @__PURE__ */ new Date()).toISOString()
|
|
2176
|
+
]);
|
|
2177
|
+
} finally {
|
|
2178
|
+
closeDatabase(db);
|
|
2179
|
+
}
|
|
2180
|
+
}
|
|
2181
|
+
function readString$1(row, name) {
|
|
2182
|
+
const value = readProperty$1(row, name);
|
|
2183
|
+
return typeof value === "string" ? value : null;
|
|
2184
|
+
}
|
|
2185
|
+
function readNumber(row, name) {
|
|
2186
|
+
const value = readProperty$1(row, name);
|
|
2187
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
2188
|
+
}
|
|
2189
|
+
function logFromJson(value) {
|
|
2190
|
+
if (value === null) return null;
|
|
2191
|
+
try {
|
|
2192
|
+
const parsed = JSON.parse(value);
|
|
2193
|
+
const result = CapturedLogSchema.safeParse(parsed);
|
|
2194
|
+
return result.success ? result.data : null;
|
|
2195
|
+
} catch {
|
|
2196
|
+
return null;
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
function logsFromRows(rows) {
|
|
2200
|
+
const logs = [];
|
|
2201
|
+
for (const row of rows) {
|
|
2202
|
+
const log = logFromJson(readString$1(row, "log_json"));
|
|
2203
|
+
if (log !== null) logs.push(log);
|
|
2204
|
+
}
|
|
2205
|
+
return logs;
|
|
2206
|
+
}
|
|
2207
|
+
async function listArchivedSessionLogs(sessionId) {
|
|
2208
|
+
const db = await openSessionArchiveDb(getSessionArchivePath(sessionId), false);
|
|
2209
|
+
if (db === null) return [];
|
|
2210
|
+
try {
|
|
2211
|
+
const rows = allPrepared(
|
|
2212
|
+
db,
|
|
2213
|
+
"SELECT log_json FROM session_logs WHERE session_id = ? ORDER BY id ASC",
|
|
2214
|
+
[sessionId]
|
|
2215
|
+
);
|
|
2216
|
+
return logsFromRows(rows);
|
|
2217
|
+
} finally {
|
|
2218
|
+
closeDatabase(db);
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
async function listArchivedSessionIds() {
|
|
2222
|
+
const archivePaths = await listArchiveDatabasePaths();
|
|
2223
|
+
const sessionIds = /* @__PURE__ */ new Set();
|
|
2224
|
+
for (const archivePath of archivePaths) {
|
|
2225
|
+
const db = await openSessionArchiveDb(archivePath, false);
|
|
2226
|
+
if (db === null) continue;
|
|
2227
|
+
try {
|
|
2228
|
+
const rows = allPrepared(
|
|
2229
|
+
db,
|
|
2230
|
+
"SELECT DISTINCT session_id FROM session_logs ORDER BY session_id ASC"
|
|
2231
|
+
);
|
|
2232
|
+
for (const row of rows) {
|
|
2233
|
+
const sessionId = readString$1(row, "session_id");
|
|
2234
|
+
if (sessionId !== null && sessionId.length > 0) sessionIds.add(sessionId);
|
|
2235
|
+
}
|
|
2236
|
+
} finally {
|
|
2237
|
+
closeDatabase(db);
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
return [...sessionIds].sort();
|
|
2241
|
+
}
|
|
2242
|
+
async function listArchiveDatabasePaths() {
|
|
2243
|
+
const root = getSessionArchiveRoot();
|
|
2244
|
+
if (!existsSync(root)) return [];
|
|
2245
|
+
try {
|
|
2246
|
+
const entries = await readdir(root, { withFileTypes: true });
|
|
2247
|
+
const paths = [];
|
|
2248
|
+
for (const entry of entries) {
|
|
2249
|
+
if (!entry.isDirectory()) continue;
|
|
2250
|
+
const candidate = join(root, entry.name, SESSION_ARCHIVE_FILE);
|
|
2251
|
+
if (existsSync(candidate)) paths.push(candidate);
|
|
2252
|
+
}
|
|
2253
|
+
return paths;
|
|
2254
|
+
} catch (err) {
|
|
2255
|
+
logger.warn("[sessionArchive] Failed to list session archives:", String(err));
|
|
2256
|
+
return [];
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
async function findArchivedLogById(id) {
|
|
2260
|
+
const archivePaths = await listArchiveDatabasePaths();
|
|
2261
|
+
for (const archivePath of archivePaths) {
|
|
2262
|
+
const db = await openSessionArchiveDb(archivePath, false);
|
|
2263
|
+
if (db === null) continue;
|
|
2264
|
+
try {
|
|
2265
|
+
const rows = allPrepared(db, "SELECT log_json FROM session_logs WHERE id = ? LIMIT 1", [id]);
|
|
2266
|
+
const first = logsFromRows(rows)[0];
|
|
2267
|
+
if (first !== void 0) return first;
|
|
2268
|
+
} finally {
|
|
2269
|
+
closeDatabase(db);
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
return null;
|
|
2273
|
+
}
|
|
2274
|
+
function placeholders(count) {
|
|
2275
|
+
return Array.from({ length: count }, () => "?").join(", ");
|
|
2276
|
+
}
|
|
2277
|
+
function idsFromRows(rows) {
|
|
2278
|
+
const ids = /* @__PURE__ */ new Set();
|
|
2279
|
+
for (const row of rows) {
|
|
2280
|
+
const id = readNumber(row, "id");
|
|
2281
|
+
if (id !== null && Number.isInteger(id)) ids.add(id);
|
|
2282
|
+
}
|
|
2283
|
+
return ids;
|
|
2284
|
+
}
|
|
2285
|
+
async function deleteArchivedLogsByIds(ids) {
|
|
2286
|
+
if (ids.size === 0) return /* @__PURE__ */ new Set();
|
|
2287
|
+
const removedIds = /* @__PURE__ */ new Set();
|
|
2288
|
+
const idValues = [...ids];
|
|
2289
|
+
const sqlPlaceholders = placeholders(idValues.length);
|
|
2290
|
+
const archivePaths = await listArchiveDatabasePaths();
|
|
2291
|
+
for (const archivePath of archivePaths) {
|
|
2292
|
+
const db = await openSessionArchiveDb(archivePath, false);
|
|
2293
|
+
if (db === null) continue;
|
|
2294
|
+
try {
|
|
2295
|
+
const matchingRows = allPrepared(
|
|
2296
|
+
db,
|
|
2297
|
+
`SELECT id FROM session_logs WHERE id IN (${sqlPlaceholders})`,
|
|
2298
|
+
idValues
|
|
2299
|
+
);
|
|
2300
|
+
const matchingIds = idsFromRows(matchingRows);
|
|
2301
|
+
if (matchingIds.size === 0) continue;
|
|
2302
|
+
if (runPrepared(db, `DELETE FROM session_logs WHERE id IN (${sqlPlaceholders})`, idValues)) {
|
|
2303
|
+
for (const id of matchingIds) {
|
|
2304
|
+
removedIds.add(id);
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
} finally {
|
|
2308
|
+
closeDatabase(db);
|
|
2309
|
+
}
|
|
2310
|
+
}
|
|
2311
|
+
return removedIds;
|
|
2312
|
+
}
|
|
2313
|
+
async function clearSessionArchives() {
|
|
2314
|
+
const root = getSessionArchiveRoot();
|
|
2315
|
+
if (!existsSync(root)) return 0;
|
|
2316
|
+
const archivePaths = await listArchiveDatabasePaths();
|
|
2317
|
+
try {
|
|
2318
|
+
await rm(root, { recursive: true, force: true });
|
|
2319
|
+
return archivePaths.length;
|
|
2320
|
+
} catch (err) {
|
|
2321
|
+
logger.warn("[sessionArchive] Failed to clear session archives:", String(err));
|
|
2322
|
+
return 0;
|
|
2323
|
+
}
|
|
2324
|
+
}
|
|
1989
2325
|
const IDLE_TIMEOUT_MS = Number(process.env["SESSION_PROCESS_IDLE_MS"]) || 5 * 60 * 1e3;
|
|
1990
2326
|
const MAX_RESTARTS = 3;
|
|
1991
2327
|
const _processes = /* @__PURE__ */ new Map();
|
|
@@ -2286,6 +2622,7 @@ const MAX_MEMORY_CACHE = 100;
|
|
|
2286
2622
|
const memoryCache = /* @__PURE__ */ new Map();
|
|
2287
2623
|
const MAX_CURSOR_PAGE_INDEXES = 16;
|
|
2288
2624
|
const logCursorPageIndexes = /* @__PURE__ */ new Map();
|
|
2625
|
+
let sessionArchiveQueue = Promise.resolve();
|
|
2289
2626
|
function cursorPageIndexKey(options) {
|
|
2290
2627
|
return JSON.stringify({
|
|
2291
2628
|
sessionId: options.sessionId ?? null,
|
|
@@ -2355,6 +2692,17 @@ function addToCache(log) {
|
|
|
2355
2692
|
upsertLogCursorPageIndexes(cachedLog);
|
|
2356
2693
|
evictOldestIfNeeded();
|
|
2357
2694
|
}
|
|
2695
|
+
function archiveLogSnapshot(log) {
|
|
2696
|
+
const archivedLog = normalizeLog(log);
|
|
2697
|
+
sessionArchiveQueue = sessionArchiveQueue.catch(() => void 0).then(async () => {
|
|
2698
|
+
await archiveSessionLog(archivedLog);
|
|
2699
|
+
}).catch((err) => {
|
|
2700
|
+
logger.warn("[store] Failed to archive session log:", String(err));
|
|
2701
|
+
});
|
|
2702
|
+
}
|
|
2703
|
+
async function flushSessionArchiveWrites() {
|
|
2704
|
+
await sessionArchiveQueue;
|
|
2705
|
+
}
|
|
2358
2706
|
function removeFromCache(id) {
|
|
2359
2707
|
memoryCache.delete(id);
|
|
2360
2708
|
removeLogsFromCursorPageIndexes(/* @__PURE__ */ new Set([id]));
|
|
@@ -2443,6 +2791,7 @@ async function addTestLogEntry(entry) {
|
|
|
2443
2791
|
await addToIndex(id, logFile, -1, -1, createLogIndexEntryMetadata(log));
|
|
2444
2792
|
});
|
|
2445
2793
|
addToCache(log);
|
|
2794
|
+
archiveLogSnapshot(log);
|
|
2446
2795
|
observeSessionLog(log, session.source);
|
|
2447
2796
|
emitLogUpdate(log);
|
|
2448
2797
|
return log;
|
|
@@ -2506,15 +2855,26 @@ async function createLog(method, path2, requestBody, headers, clientInfo, rawHea
|
|
|
2506
2855
|
await addToIndex(id, logFile, -1, -1, createLogIndexEntryMetadata(log));
|
|
2507
2856
|
});
|
|
2508
2857
|
addToCache(log);
|
|
2858
|
+
archiveLogSnapshot(log);
|
|
2509
2859
|
markSessionStarted(log, session.source);
|
|
2510
2860
|
emitLogUpdate(log);
|
|
2511
2861
|
return log;
|
|
2512
2862
|
}
|
|
2513
2863
|
function finalizeLogUpdate(log) {
|
|
2514
2864
|
addToCache(log);
|
|
2865
|
+
archiveLogSnapshot(log);
|
|
2515
2866
|
markSessionFinished(log);
|
|
2516
2867
|
emitLogUpdate(log);
|
|
2517
2868
|
}
|
|
2869
|
+
async function getArchivedLogByIdForStore(id) {
|
|
2870
|
+
await flushSessionArchiveWrites();
|
|
2871
|
+
const archivedLog = await findArchivedLogById(id);
|
|
2872
|
+
if (archivedLog === null) return null;
|
|
2873
|
+
const normalized = normalizeLog(archivedLog);
|
|
2874
|
+
addToCache(normalized);
|
|
2875
|
+
observeSessionLog(normalized);
|
|
2876
|
+
return normalized;
|
|
2877
|
+
}
|
|
2518
2878
|
async function getLogById(id) {
|
|
2519
2879
|
const cached = memoryCache.get(id);
|
|
2520
2880
|
if (cached !== void 0) {
|
|
@@ -2522,12 +2882,12 @@ async function getLogById(id) {
|
|
|
2522
2882
|
}
|
|
2523
2883
|
const entry = await findInIndex(id);
|
|
2524
2884
|
if (entry === null) {
|
|
2525
|
-
return
|
|
2885
|
+
return await getArchivedLogByIdForStore(id);
|
|
2526
2886
|
}
|
|
2527
2887
|
try {
|
|
2528
2888
|
const filePath = join(resolveLogDir(), entry.file);
|
|
2529
2889
|
if (!existsSync(filePath)) {
|
|
2530
|
-
return
|
|
2890
|
+
return await getArchivedLogByIdForStore(id);
|
|
2531
2891
|
}
|
|
2532
2892
|
if (entry.byteOffset >= 0 && entry.byteLength > 0) {
|
|
2533
2893
|
const fh = await open(filePath, "r");
|
|
@@ -2559,7 +2919,7 @@ async function getLogById(id) {
|
|
|
2559
2919
|
} catch (err) {
|
|
2560
2920
|
logger.error("[store] Failed to read log from disk:", String(err));
|
|
2561
2921
|
}
|
|
2562
|
-
return
|
|
2922
|
+
return await getArchivedLogByIdForStore(id);
|
|
2563
2923
|
}
|
|
2564
2924
|
async function scanLogFileForId(filePath, id) {
|
|
2565
2925
|
let lastMatch = null;
|
|
@@ -2634,6 +2994,16 @@ async function visitPersistedLogFile(filePath, visitor) {
|
|
|
2634
2994
|
logger.error("[store] Failed to read persisted log file:", filePath, String(err));
|
|
2635
2995
|
}
|
|
2636
2996
|
}
|
|
2997
|
+
async function visitArchivedSessionLogs(sessionId, visitor) {
|
|
2998
|
+
if (sessionId === void 0) return;
|
|
2999
|
+
await flushSessionArchiveWrites();
|
|
3000
|
+
const logs = await listArchivedSessionLogs(sessionId);
|
|
3001
|
+
for (const archivedLog of logs) {
|
|
3002
|
+
const log = normalizeLog(archivedLog);
|
|
3003
|
+
observeSessionLog(log);
|
|
3004
|
+
visitor(log);
|
|
3005
|
+
}
|
|
3006
|
+
}
|
|
2637
3007
|
function canUseIndexedListPage(options) {
|
|
2638
3008
|
return options.sessionId === void 0 && options.model === void 0;
|
|
2639
3009
|
}
|
|
@@ -2698,6 +3068,7 @@ async function listLogsPage(options) {
|
|
|
2698
3068
|
observeSessionLog(log);
|
|
2699
3069
|
visitLog(log);
|
|
2700
3070
|
});
|
|
3071
|
+
await visitArchivedSessionLogs(options.sessionId, visitLog);
|
|
2701
3072
|
for (const log of memoryCache.values()) {
|
|
2702
3073
|
visitLog(log);
|
|
2703
3074
|
}
|
|
@@ -2785,6 +3156,17 @@ async function buildLogCursorPageIndexFromLogIndex(options, allowRebuild) {
|
|
|
2785
3156
|
idsById.add(log.id);
|
|
2786
3157
|
logsById.set(log.id, log);
|
|
2787
3158
|
}
|
|
3159
|
+
if (options.sessionId !== void 0) {
|
|
3160
|
+
await flushSessionArchiveWrites();
|
|
3161
|
+
const archivedLogs = await listArchivedSessionLogs(options.sessionId);
|
|
3162
|
+
for (const archivedLog of archivedLogs) {
|
|
3163
|
+
const log = normalizeLog(archivedLog);
|
|
3164
|
+
if (!matchesLogFilters(log, options.sessionId, options.model)) continue;
|
|
3165
|
+
observeSessionLog(log);
|
|
3166
|
+
idsById.add(log.id);
|
|
3167
|
+
logsById.set(log.id, log);
|
|
3168
|
+
}
|
|
3169
|
+
}
|
|
2788
3170
|
return {
|
|
2789
3171
|
key: cursorPageIndexKey(options),
|
|
2790
3172
|
sessionId: options.sessionId,
|
|
@@ -2807,6 +3189,7 @@ async function buildLogCursorPageIndex(options) {
|
|
|
2807
3189
|
observeSessionLog(log);
|
|
2808
3190
|
visitLog(log);
|
|
2809
3191
|
});
|
|
3192
|
+
await visitArchivedSessionLogs(options.sessionId, visitLog);
|
|
2810
3193
|
for (const log of memoryCache.values()) {
|
|
2811
3194
|
visitLog(log);
|
|
2812
3195
|
}
|
|
@@ -2899,6 +3282,15 @@ async function collectSessionLogSummaries(sessionId, includeHistory) {
|
|
|
2899
3282
|
for (const summary of indexedSummaries) {
|
|
2900
3283
|
summariesById.set(summary.id, summary);
|
|
2901
3284
|
}
|
|
3285
|
+
await flushSessionArchiveWrites();
|
|
3286
|
+
const archivedLogs = await listArchivedSessionLogs(sessionId);
|
|
3287
|
+
for (const archivedLog of archivedLogs) {
|
|
3288
|
+
const log = normalizeLog(archivedLog);
|
|
3289
|
+
observeSessionLog(log);
|
|
3290
|
+
if (!summariesById.has(log.id)) {
|
|
3291
|
+
summariesById.set(log.id, buildSessionLogSummary(log));
|
|
3292
|
+
}
|
|
3293
|
+
}
|
|
2902
3294
|
if (includeHistory && summariesById.size === 0) {
|
|
2903
3295
|
await visitPersistedLogs((log) => {
|
|
2904
3296
|
observeSessionLog(log);
|
|
@@ -2954,8 +3346,13 @@ async function getSessionInfo(sessionId, options) {
|
|
|
2954
3346
|
latestLogLimit: options.latestLogLimit
|
|
2955
3347
|
});
|
|
2956
3348
|
}
|
|
2957
|
-
function
|
|
2958
|
-
|
|
3349
|
+
async function listSessions() {
|
|
3350
|
+
await flushSessionArchiveWrites();
|
|
3351
|
+
const sessionIds = new Set(getSessionIds());
|
|
3352
|
+
for (const sessionId of await listArchivedSessionIds()) {
|
|
3353
|
+
sessionIds.add(sessionId);
|
|
3354
|
+
}
|
|
3355
|
+
return [...sessionIds].sort();
|
|
2959
3356
|
}
|
|
2960
3357
|
function getModels() {
|
|
2961
3358
|
const set = /* @__PURE__ */ new Set();
|
|
@@ -2999,8 +3396,13 @@ function collectDirectoryStats(dir, shouldCount) {
|
|
|
2999
3396
|
function getLogStorageStats() {
|
|
3000
3397
|
const logDir = resolveLogDir();
|
|
3001
3398
|
const chunkDir = getChunksDir();
|
|
3399
|
+
const sessionArchiveDir = getSessionArchiveRoot();
|
|
3002
3400
|
const logStats = collectDirectoryStats(logDir, (fileName) => fileName.endsWith(".jsonl"));
|
|
3003
3401
|
const chunkStats = collectDirectoryStats(chunkDir, (fileName) => fileName.endsWith(".json"));
|
|
3402
|
+
const sessionArchiveStats = collectDirectoryStats(
|
|
3403
|
+
sessionArchiveDir,
|
|
3404
|
+
(fileName) => fileName === "session.sqlite" || fileName.startsWith("session.sqlite-")
|
|
3405
|
+
);
|
|
3004
3406
|
return {
|
|
3005
3407
|
memoryCount: memoryCache.size,
|
|
3006
3408
|
logDir,
|
|
@@ -3008,7 +3410,10 @@ function getLogStorageStats() {
|
|
|
3008
3410
|
logBytes: logStats.bytes,
|
|
3009
3411
|
chunkDir,
|
|
3010
3412
|
chunkFileCount: chunkStats.fileCount,
|
|
3011
|
-
chunkBytes: chunkStats.bytes
|
|
3413
|
+
chunkBytes: chunkStats.bytes,
|
|
3414
|
+
sessionArchiveDir,
|
|
3415
|
+
sessionArchiveFileCount: sessionArchiveStats.fileCount,
|
|
3416
|
+
sessionArchiveBytes: sessionArchiveStats.bytes
|
|
3012
3417
|
};
|
|
3013
3418
|
}
|
|
3014
3419
|
function clearAllLogs() {
|
|
@@ -3043,8 +3448,9 @@ async function deleteMatchingFiles(dir, shouldDelete) {
|
|
|
3043
3448
|
async function clearPersistedLogStorage() {
|
|
3044
3449
|
return await runWithFlushedLogWriteLock(async () => {
|
|
3045
3450
|
await flushIndex();
|
|
3451
|
+
await flushSessionArchiveWrites();
|
|
3046
3452
|
const result = clearAllLogs();
|
|
3047
|
-
const [logFilesDeleted, chunkFilesDeleted] = await Promise.all([
|
|
3453
|
+
const [logFilesDeleted, chunkFilesDeleted, sessionArchiveFilesDeleted] = await Promise.all([
|
|
3048
3454
|
deleteMatchingFiles(
|
|
3049
3455
|
resolveLogDir(),
|
|
3050
3456
|
(fileName) => fileName.endsWith(".jsonl") || fileName === "logs.idx" || fileName === "inspector.sqlite" || fileName.startsWith("inspector.sqlite-")
|
|
@@ -3052,13 +3458,15 @@ async function clearPersistedLogStorage() {
|
|
|
3052
3458
|
deleteMatchingFiles(
|
|
3053
3459
|
getChunksDir(),
|
|
3054
3460
|
(fileName) => fileName.endsWith(".json") || fileName.startsWith(".") && fileName.endsWith(".tmp")
|
|
3055
|
-
)
|
|
3461
|
+
),
|
|
3462
|
+
clearSessionArchives()
|
|
3056
3463
|
]);
|
|
3057
3464
|
await rebuildIndex();
|
|
3058
3465
|
return {
|
|
3059
3466
|
cleared: result.cleared,
|
|
3060
3467
|
logFilesDeleted,
|
|
3061
|
-
chunkFilesDeleted
|
|
3468
|
+
chunkFilesDeleted,
|
|
3469
|
+
sessionArchiveFilesDeleted
|
|
3062
3470
|
};
|
|
3063
3471
|
});
|
|
3064
3472
|
}
|
|
@@ -3214,18 +3622,25 @@ async function deleteChunkFilesByIds(ids) {
|
|
|
3214
3622
|
async function clearPersistedLogsByIds(ids) {
|
|
3215
3623
|
const uniqueIds = new Set(ids);
|
|
3216
3624
|
if (uniqueIds.size === 0) {
|
|
3217
|
-
return {
|
|
3625
|
+
return {
|
|
3626
|
+
cleared: 0,
|
|
3627
|
+
logFilesRewritten: 0,
|
|
3628
|
+
chunkFilesDeleted: 0,
|
|
3629
|
+
sessionArchiveLogsDeleted: 0
|
|
3630
|
+
};
|
|
3218
3631
|
}
|
|
3219
3632
|
return await runWithFlushedLogWriteLock(async () => {
|
|
3220
3633
|
await flushIndex();
|
|
3634
|
+
await flushSessionArchiveWrites();
|
|
3221
3635
|
const memoryRemovedIds = /* @__PURE__ */ new Set();
|
|
3222
3636
|
for (const id of uniqueIds) {
|
|
3223
3637
|
if (memoryCache.has(id)) memoryRemovedIds.add(id);
|
|
3224
3638
|
}
|
|
3225
3639
|
const result = clearLogsByIds([...uniqueIds]);
|
|
3226
|
-
const [rewriteResult, chunkFilesDeleted] = await Promise.all([
|
|
3640
|
+
const [rewriteResult, chunkFilesDeleted, archivedRemovedIds] = await Promise.all([
|
|
3227
3641
|
rewriteLogFilesWithoutIds(uniqueIds),
|
|
3228
|
-
deleteChunkFilesByIds(uniqueIds)
|
|
3642
|
+
deleteChunkFilesByIds(uniqueIds),
|
|
3643
|
+
deleteArchivedLogsByIds(uniqueIds)
|
|
3229
3644
|
]);
|
|
3230
3645
|
await rebuildIndex();
|
|
3231
3646
|
clearLogCursorPageIndexes();
|
|
@@ -3235,10 +3650,14 @@ async function clearPersistedLogsByIds(ids) {
|
|
|
3235
3650
|
clearedIds.add(id);
|
|
3236
3651
|
}
|
|
3237
3652
|
}
|
|
3653
|
+
for (const id of archivedRemovedIds) {
|
|
3654
|
+
clearedIds.add(id);
|
|
3655
|
+
}
|
|
3238
3656
|
return {
|
|
3239
3657
|
cleared: clearedIds.size,
|
|
3240
3658
|
logFilesRewritten: rewriteResult.logFilesRewritten,
|
|
3241
|
-
chunkFilesDeleted
|
|
3659
|
+
chunkFilesDeleted,
|
|
3660
|
+
sessionArchiveLogsDeleted: archivedRemovedIds.size
|
|
3242
3661
|
};
|
|
3243
3662
|
});
|
|
3244
3663
|
}
|
|
@@ -6426,7 +6845,7 @@ const Route$z = createFileRoute("/api/sessions")({
|
|
|
6426
6845
|
if (details === "true" || details === "1") {
|
|
6427
6846
|
return Response.json(getSessionSnapshots());
|
|
6428
6847
|
}
|
|
6429
|
-
return Response.json(
|
|
6848
|
+
return Response.json(await listSessions());
|
|
6430
6849
|
}
|
|
6431
6850
|
}
|
|
6432
6851
|
}
|
|
@@ -7926,7 +8345,7 @@ const Route$w = createFileRoute("/api/models")({
|
|
|
7926
8345
|
}
|
|
7927
8346
|
}
|
|
7928
8347
|
});
|
|
7929
|
-
const version = "2.1.
|
|
8348
|
+
const version = "2.1.8";
|
|
7930
8349
|
const packageJson = {
|
|
7931
8350
|
version
|
|
7932
8351
|
};
|
|
@@ -9312,6 +9731,15 @@ function mcpConfig() {
|
|
|
9312
9731
|
}
|
|
9313
9732
|
}
|
|
9314
9733
|
},
|
|
9734
|
+
mimoCodeLocal: {
|
|
9735
|
+
mcp: {
|
|
9736
|
+
"agent-inspector": {
|
|
9737
|
+
type: "local",
|
|
9738
|
+
command: ["agent-inspector-mcp", "stdio", "--url", endpoint],
|
|
9739
|
+
enabled: true
|
|
9740
|
+
}
|
|
9741
|
+
}
|
|
9742
|
+
},
|
|
9315
9743
|
networkNote: "If the MCP client runs in another container or host, replace localhost with an address reachable from that client. Configure only one transport for the same Inspector instance."
|
|
9316
9744
|
};
|
|
9317
9745
|
}
|
|
@@ -9635,7 +10063,7 @@ function registerTools(server) {
|
|
|
9635
10063
|
title: string().min(1).optional().describe("Human-readable run title."),
|
|
9636
10064
|
task: string().nullable().optional().describe("Task statement or benchmark case."),
|
|
9637
10065
|
project: string().nullable().optional().describe("Project or repository under test."),
|
|
9638
|
-
agent: string().nullable().optional().describe("Coding agent name, e.g. Codex/OpenCode."),
|
|
10066
|
+
agent: string().nullable().optional().describe("Coding agent name, e.g. Codex/OpenCode/MiMo Code."),
|
|
9639
10067
|
status: InspectorRunStatusSchema.optional().describe("Initial run status."),
|
|
9640
10068
|
tags: array(string()).optional().describe("Free-form run labels."),
|
|
9641
10069
|
metadata: record(string(), JsonValueSchema).optional().describe("JSON metadata.")
|
|
@@ -9724,7 +10152,7 @@ function registerTools(server) {
|
|
|
9724
10152
|
"inspector_create_group",
|
|
9725
10153
|
{
|
|
9726
10154
|
title: "Create or declare an Inspector group",
|
|
9727
|
-
description: "Creates an evaluation/batch group that external systems can use to aggregate multiple
|
|
10155
|
+
description: "Creates an evaluation/batch group that external systems can use to aggregate multiple Codex, OpenCode, or MiMo Code sessions across models such as MiniMax, DeepSeek, or GLM.",
|
|
9728
10156
|
inputSchema: object({
|
|
9729
10157
|
groupId: string().min(1).optional().describe("Stable group id. Generated when omitted."),
|
|
9730
10158
|
title: string().min(1).optional().describe("Human-readable group title."),
|
|
@@ -9775,7 +10203,7 @@ function registerTools(server) {
|
|
|
9775
10203
|
"inspector_add_group_session",
|
|
9776
10204
|
{
|
|
9777
10205
|
title: "Attach a session to an Inspector group",
|
|
9778
|
-
description: "Adds or updates one group member. Use it after each
|
|
10206
|
+
description: "Adds or updates one group member. Use it after each coding-agent process discovers its session id, or while an evaluation matrix is running to attach model/provider labels.",
|
|
9779
10207
|
inputSchema: AddInspectorGroupSessionInputSchema.extend({
|
|
9780
10208
|
groupId: string().min(1).describe("The Inspector group id.")
|
|
9781
10209
|
})
|
|
@@ -10015,7 +10443,7 @@ function registerResources(server) {
|
|
|
10015
10443
|
"inspector://mcp/config",
|
|
10016
10444
|
{
|
|
10017
10445
|
title: "Inspector MCP client config",
|
|
10018
|
-
description: "Streamable HTTP, stdio bridge, and
|
|
10446
|
+
description: "Streamable HTTP, stdio bridge, OpenCode, and MiMo Code MCP configuration snippets.",
|
|
10019
10447
|
mimeType: "application/json"
|
|
10020
10448
|
},
|
|
10021
10449
|
(uri) => jsonResource(uri, mcpConfig())
|
|
@@ -10631,7 +11059,8 @@ const Route$u = createFileRoute("/api/logs")({
|
|
|
10631
11059
|
success: true,
|
|
10632
11060
|
cleared: result2.cleared,
|
|
10633
11061
|
logFilesRewritten: result2.logFilesRewritten,
|
|
10634
|
-
chunkFilesDeleted: result2.chunkFilesDeleted
|
|
11062
|
+
chunkFilesDeleted: result2.chunkFilesDeleted,
|
|
11063
|
+
sessionArchiveLogsDeleted: result2.sessionArchiveLogsDeleted
|
|
10635
11064
|
});
|
|
10636
11065
|
}
|
|
10637
11066
|
const result = await clearPersistedLogStorage();
|
|
@@ -10639,7 +11068,8 @@ const Route$u = createFileRoute("/api/logs")({
|
|
|
10639
11068
|
success: true,
|
|
10640
11069
|
cleared: result.cleared,
|
|
10641
11070
|
logFilesDeleted: result.logFilesDeleted,
|
|
10642
|
-
chunkFilesDeleted: result.chunkFilesDeleted
|
|
11071
|
+
chunkFilesDeleted: result.chunkFilesDeleted,
|
|
11072
|
+
sessionArchiveFilesDeleted: result.sessionArchiveFilesDeleted
|
|
10643
11073
|
});
|
|
10644
11074
|
}
|
|
10645
11075
|
}
|