src / index.ts
import { tool, type PluginContext, type ToolsProviderController } from "@lmstudio/sdk";
import { z } from "zod";
import { globalConfigSchematics } from "./config";
import { consult, errorText } from "./expert";
export async function toolsProvider(ctl: ToolsProviderController) {
const config = ctl.getGlobalPluginConfig(globalConfigSchematics);
let used = false;
return [tool({
name: "consult_deepseek",
description: "PAID EXTERNAL EXPERT, scarce fallback. Use ONLY when the user explicitly asks to consult DeepSeek/a large external model, OR when your own knowledge is insufficient to answer reliably after appropriate ordinary tools. Do not use for routine conversation, rewriting, known facts, repeated confirmation, or optional second opinions. At most ONE consultation for the current user question. Send one precise question plus only essential context, NEVER the full chat or your internal reasoning. After receiving the answer, respond naturally in Russian and disclose the consultation. Do not verify DeepSeek by calling it again. This tool sends the submitted text to DeepSeek's official API; it does not search the web.",
parameters: {
question: z.string().min(3).max(10000).describe("One precise self-contained question. No full chat history."),
context: z.string().max(4000).default("").describe("Only indispensable facts, otherwise empty."),
reason: z.enum(["explicit_user_request", "insufficient_knowledge"]).describe("Why this external consultation is necessary."),
uncertainty: z.string().min(3).max(500).describe("Specific missing knowledge, or the user's explicit request."),
},
implementation: async (args) => {
if (used) return "Лимит: эксперт уже был запрошен в этой генерации. Не вызывай инструмент повторно; ответь по имеющимся данным.";
used = true;
try {
return await consult(args, {
keyFile: config.get("keyFile"), model: config.get("model"),
maxOutput: config.get("maxOutput"), thinking: config.get("thinking"),
dailyCalls: config.get("dailyCalls"), dailyTokens: config.get("dailyTokens"),
}, ctl.abortSignal);
} catch (error) {
return `Консультация не завершена: ${errorText(error)} Не повторяй запрос автоматически.`;
}
},
})];
}
export async function main(context: PluginContext) {
context.withGlobalConfigSchematics(globalConfigSchematics).withToolsProvider(toolsProvider);
}
src / index.ts
import { tool, type PluginContext, type ToolsProviderController } from "@lmstudio/sdk";
import { z } from "zod";
import { globalConfigSchematics } from "./config";
import { consult, errorText } from "./expert";
export async function toolsProvider(ctl: ToolsProviderController) {
const config = ctl.getGlobalPluginConfig(globalConfigSchematics);
let used = false;
return [tool({
name: "consult_deepseek",
description: "PAID EXTERNAL EXPERT, scarce fallback. Use ONLY when the user explicitly asks to consult DeepSeek/a large external model, OR when your own knowledge is insufficient to answer reliably after appropriate ordinary tools. Do not use for routine conversation, rewriting, known facts, repeated confirmation, or optional second opinions. At most ONE consultation for the current user question. Send one precise question plus only essential context, NEVER the full chat or your internal reasoning. After receiving the answer, respond naturally in Russian and disclose the consultation. Do not verify DeepSeek by calling it again. This tool sends the submitted text to DeepSeek's official API; it does not search the web.",
parameters: {
question: z.string().min(3).max(10000).describe("One precise self-contained question. No full chat history."),
context: z.string().max(4000).default("").describe("Only indispensable facts, otherwise empty."),
reason: z.enum(["explicit_user_request", "insufficient_knowledge"]).describe("Why this external consultation is necessary."),
uncertainty: z.string().min(3).max(500).describe("Specific missing knowledge, or the user's explicit request."),
},
implementation: async (args) => {
if (used) return "Лимит: эксперт уже был запрошен в этой генерации. Не вызывай инструмент повторно; ответь по имеющимся данным.";
used = true;
try {
return await consult(args, {
keyFile: config.get("keyFile"), model: config.get("model"),
maxOutput: config.get("maxOutput"), thinking: config.get("thinking"),
dailyCalls: config.get("dailyCalls"), dailyTokens: config.get("dailyTokens"),
}, ctl.abortSignal);
} catch (error) {
return `Консультация не завершена: ${errorText(error)} Не повторяй запрос автоматически.`;
}
},
})];
}
export async function main(context: PluginContext) {
context.withGlobalConfigSchematics(globalConfigSchematics).withToolsProvider(toolsProvider);
}