src / pluginHealth.ts
src / pluginHealth.ts
/**
* Health / status tools that the main model (and user) can call.
* Wire these into toolsProvider with a simple registration block.
*/
import { tool } from "@lmstudio/sdk";
import { z } from "zod";
import { queryState, getState } from "./stateRegistry";
import { getCacheStats, clearAllCaches } from "./tools/cacheTools";
import { checkDependencies, formatDependencyStatus } from "./dependencyChecker";
/**
* Returns a ready-to-register array of health tools.
* Call from toolsProvider and push(...createHealthTools()).
*/
export function createHealthTools(): any[] {
const tools: any[] = [];
tools.push(
tool({
name: "plugin_status",
description:
"Get a live snapshot of plugin health: active agents, background tasks, cache stats, dependency availability, and config version. Prefer this over guessing system state.",
parameters: {
detail: z
.enum(["summary", "full", "cache", "agents", "background", "deps"])
.optional()
.default("summary")
.describe("How much detail to return"),
},
implementation: async ({ detail = "summary" }) => {
const s = getState();
if (detail === "cache") {
return {
...queryState("cache").data,
detailed: getCacheStats(),
};
}
if (detail === "agents") return queryState("agents").data;
if (detail === "background") return queryState("background").data;
if (detail === "deps") {
const deps = s.dependencyStatus ?? (await checkDependencies());
return {
status: deps,
formatted: formatDependencyStatus(deps),
};
}
if (detail === "full") return queryState("full").data;
// summary
return {
uptimeMs: Date.now() - s.sessionStart.getTime(),
predictions: s.totalPredictions,
configVersion: s.configVersion,
cacheHitRate:
Math.round(
(s.cacheHits / (s.cacheHits + s.cacheMisses || 1)) * 100,
) || 0,
activeAgents: Array.from(s.activeAgents.values()).filter(
(a) => a.status === "active",
).length,
runningBackground: Array.from(s.backgroundTasks.values()).filter(
(t) => t.status === "running",
).length,
missingDeps: Object.entries(s.dependencyStatus ?? {})
.filter(([, v]) => v === "unavailable")
.map(([k]) => k),
};
},
}),
);
tools.push(
tool({
name: "clear_plugin_caches",
description:
"Clear all in-memory plugin caches (RAG, web fetch, file read). Useful after large file changes or when stale results are suspected.",
parameters: {},
implementation: async () => {
const result = clearAllCaches();
// Also clear the tool-result cache if the caller exposes it via global
return result;
},
}),
);
return tools;
}
/**
* Health / status tools that the main model (and user) can call.
* Wire these into toolsProvider with a simple registration block.
*/
import { tool } from "@lmstudio/sdk";
import { z } from "zod";
import { queryState, getState } from "./stateRegistry";
import { getCacheStats, clearAllCaches } from "./tools/cacheTools";
import { checkDependencies, formatDependencyStatus } from "./dependencyChecker";
/**
* Returns a ready-to-register array of health tools.
* Call from toolsProvider and push(...createHealthTools()).
*/
export function createHealthTools(): any[] {
const tools: any[] = [];
tools.push(
tool({
name: "plugin_status",
description:
"Get a live snapshot of plugin health: active agents, background tasks, cache stats, dependency availability, and config version. Prefer this over guessing system state.",
parameters: {
detail: z
.enum(["summary", "full", "cache", "agents", "background", "deps"])
.optional()
.default("summary")
.describe("How much detail to return"),
},
implementation: async ({ detail = "summary" }) => {
const s = getState();
if (detail === "cache") {
return {
...queryState("cache").data,
detailed: getCacheStats(),
};
}
if (detail === "agents") return queryState("agents").data;
if (detail === "background") return queryState("background").data;
if (detail === "deps") {
const deps = s.dependencyStatus ?? (await checkDependencies());
return {
status: deps,
formatted: formatDependencyStatus(deps),
};
}
if (detail === "full") return queryState("full").data;
// summary
return {
uptimeMs: Date.now() - s.sessionStart.getTime(),
predictions: s.totalPredictions,
configVersion: s.configVersion,
cacheHitRate:
Math.round(
(s.cacheHits / (s.cacheHits + s.cacheMisses || 1)) * 100,
) || 0,
activeAgents: Array.from(s.activeAgents.values()).filter(
(a) => a.status === "active",
).length,
runningBackground: Array.from(s.backgroundTasks.values()).filter(
(t) => t.status === "running",
).length,
missingDeps: Object.entries(s.dependencyStatus ?? {})
.filter(([, v]) => v === "unavailable")
.map(([k]) => k),
};
},
}),
);
tools.push(
tool({
name: "clear_plugin_caches",
description:
"Clear all in-memory plugin caches (RAG, web fetch, file read). Useful after large file changes or when stale results are suspected.",
parameters: {},
implementation: async () => {
const result = clearAllCaches();
// Also clear the tool-result cache if the caller exposes it via global
return result;
},
}),
);
return tools;
}