Project Files
dist / manager.js
"use strict";
/**
* @file manager.ts
* @description Persona switching logic — orchestrates profile loading and
* context management for the persona-manager plugin.
*
* Provides the core operations used by the LM Studio tools:
* - switchPersona: activate a persona by ID
* - listPersonas: enumerate available profiles
* - getCurrentPersona: query the active state
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.getContext = exports.getActivePersona = exports.DEFAULT_PERSONA_ID = void 0;
exports.switchToPersona = switchToPersona;
exports.listPersonas = listPersonas;
exports.getCurrentPersona = getCurrentPersona;
exports.savePersona = savePersona;
const loader_1 = require("./loader");
const context_1 = require("./context");
Object.defineProperty(exports, "getActivePersona", { enumerable: true, get: function () { return context_1.getActivePersona; } });
Object.defineProperty(exports, "getContext", { enumerable: true, get: function () { return context_1.getContext; } });
/**
* Default persona used when no specific profile is loaded.
*/
exports.DEFAULT_PERSONA_ID = "__default__";
// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------
/**
* Switch to a persona by ID.
* Returns the result of the switch operation.
* Throws if the persona ID is not found among loaded profiles.
*/
function switchToPersona(personaId) {
if (personaId === exports.DEFAULT_PERSONA_ID) {
// Switching to default — clear the active persona
const previous = (0, context_1.getActivePersona)();
// Use a minimal "default" profile
const defaultProfile = {
id: exports.DEFAULT_PERSONA_ID,
name: "Default",
description: "Default assistant persona — no character override.",
systemPrompt: "You are a helpful assistant.",
};
const prevId = (0, context_1.switchPersona)(defaultProfile);
return {
previousPersona: prevId,
activePersona: defaultProfile,
contextReset: true,
};
}
const profile = (0, loader_1.loadProfile)(personaId);
if (!profile) {
throw new Error(`Persona "${personaId}" not found. ` +
"Use the list tool to see available personas.");
}
const prevId = (0, context_1.switchPersona)(profile);
return {
previousPersona: prevId,
activePersona: profile,
contextReset: true,
};
}
/**
* List all available persona profiles.
* Returns a summary result suitable for returning as a tool result.
*/
function listPersonas() {
const profiles = (0, loader_1.loadAllProfiles)();
return {
personas: profiles.map((p) => ({
id: p.id,
name: p.name,
description: p.description,
tags: p.tags,
})),
count: profiles.length,
};
}
/**
* Get the currently active persona details and context.
*/
function getCurrentPersona() {
const persona = (0, context_1.getActivePersona)();
return {
active: persona !== null && persona.id !== exports.DEFAULT_PERSONA_ID,
persona,
context: (0, context_1.getContext)(),
};
}
// ---------------------------------------------------------------------------
// Save tool
// ---------------------------------------------------------------------------
/**
* Generate a kebab-case, filename-safe ID from a display name.
*/
function generateId(name) {
return name
.toLowerCase()
.trim()
.replace(/\s+/g, "-")
.replace(/[^a-z0-9-]/g, "")
.replace(/-+/g, "-")
.replace(/^-|-$/g, "");
}
/**
* Save a new persona profile to disk.
*
* Generates an ID from the display name, validates required fields,
* writes the profile JSON file, and reloads the in-memory cache.
*/
function savePersona(params) {
const { name, description, systemPrompt, greeting, tags, overwrite = false, } = params;
// Validate required fields
if (!name || typeof name !== "string" || name.trim().length === 0) {
throw new Error("Field 'name' is required and must be a non-empty string.");
}
if (!description ||
typeof description !== "string" ||
description.trim().length === 0) {
throw new Error("Field 'description' is required and must be a non-empty string.");
}
if (!systemPrompt ||
typeof systemPrompt !== "string" ||
systemPrompt.trim().length === 0) {
throw new Error("Field 'systemPrompt' is required and must be a non-empty string.");
}
const id = generateId(name);
if (!id) {
throw new Error(`Failed to generate a valid ID from name "${name}". ` +
"Name must contain at least one alphanumeric character.");
}
const profile = {
id,
name: name.trim(),
description: description.trim(),
systemPrompt: systemPrompt.trim(),
...(greeting ? { greeting: greeting.trim() } : {}),
...(tags && tags.length > 0 ? { tags } : {}),
};
const { filePath, overwritten } = (0, loader_1.saveProfileToDisk)(profile, overwrite);
return {
id: profile.id,
name: profile.name,
description: profile.description,
systemPrompt: profile.systemPrompt,
greeting: profile.greeting,
tags: profile.tags,
filePath,
success: true,
overwritten,
message: overwritten
? `Persona "${profile.name}" (${profile.id}) overwritten successfully.`
: `Persona "${profile.name}" (${profile.id}) created successfully.`,
};
}
//# sourceMappingURL=manager.js.map