/** * SkillManager - Manages skill lifecycle for an agent. * * Handles loading, unloading, validation, and injection of * skill tools, hints, global data, and prompt sections. */ import { SkillBase, type SkillConfig } from './SkillBase.js'; /** * Manages the lifecycle of skills attached to an agent. * * Handles loading, unloading, validation, and aggregation of skill tools, * hints, global data, and prompt sections. * * @remarks * **Architectural note — push vs pull model:** * Python's `SkillManager.__init__(self, agent)` stores the agent reference and * uses a **push model**: when a skill is loaded via `load_skill()`, the manager * immediately calls `agent.add_hints()`, `agent.update_global_data()`, and * `agent.prompt_add_section()` to inject skill data into the agent. * * This TypeScript implementation uses a **pull model** instead: `SkillManager` * has no agent reference and no constructor. `AgentBase` owns the manager and * calls `getAllHints()`, `getMergedGlobalData()`, and `getAllPromptSections()` * at render time. Both approaches produce the same observable behavior at the * SWML / SWAIG level. The pull model avoids circular-reference issues between * `AgentBase` and `SkillManager` and is better suited to TypeScript's * import-graph constraints. */ export declare class SkillManager { private skills; private skillMeta; /** * Public read-only view of all loaded skill instances, keyed by instance key. * Python equivalent: `self.loaded_skills` (public `Dict[str, SkillBase]`). * * Use this to iterate or inspect loaded skills without mutating the internal map. */ get loadedSkills(): ReadonlyMap; /** * Add a skill to the manager, validating env vars and calling setup(). * Uses the skill's instance key for deduplication. * * {@link loadSkill} / {@link loadSkillByName} wrap this and catch to return * `[false, msg]`, matching Python `load_skill`'s return contract * (`skill_manager.py` lines 114-118). * * @param skill - The skill instance to add. * @returns Resolves once the skill is registered. * @throws {Error} When a single-instance skill is already loaded, its * required environment variables are missing, its parameter schema is * empty, its required packages cannot be imported, or `setup()` returns * `false`. */ addSkill(skill: SkillBase): Promise; /** * Remove a skill by its instance key or instance ID, calling cleanup() before removal. * @param keyOrId - The instance key or instance ID of the skill to remove. * @returns True if the skill was found and removed, false otherwise. * * @remarks Equivalent to Python's `unload_skill(skill_identifier)`. Callers porting * from Python should change `skill_manager.unload_skill(id)` → * `skillManager.removeSkill(id)`. */ removeSkill(keyOrId: string): Promise; /** * Remove all skill instances matching a given skill name. * @param skillName - The skill name to match against. * @returns The number of skill instances removed. */ removeSkillByName(skillName: string): Promise; /** * Check if any skill instance with the given name is currently loaded. * @param skillName - The skill name to check for. * @returns True if at least one instance with this name is loaded. */ hasSkill(skillName: string): boolean; /** * Check if a skill with the given instance key is currently loaded. * This matches Python's `has_skill` semantics, which performs a direct * dictionary key lookup (`skill_identifier in self.loaded_skills`). * * Use `hasSkill(name)` to check by skill name (iterates values). * Use `hasSkillByKey(key)` to check by instance key (direct map lookup). * * @param instanceKey - The instance key to look up. * @returns True if a skill with this exact instance key is loaded. * * @remarks Equivalent to Python's `has_skill(skill_identifier)`. Callers porting * from Python should change `skill_manager.has_skill(key)` → * `skillManager.hasSkillByKey(key)`. */ hasSkillByKey(instanceKey: string): boolean; /** * Load a skill by providing the class constructor directly, bypassing the registry. * This is the TypeScript equivalent of Python's `load_skill(skill_name, skill_class, params)` * path where a caller-provided `skill_class` is used instead of a registry lookup. * * @param skillClass - The skill class constructor (a subclass of `SkillBase`). * @param config - Optional configuration to pass to the skill constructor. * @returns A tuple `[success, errorMessage]` matching Python's `load_skill` return * contract. `errorMessage` is an empty string on success. * * @remarks Equivalent to Python's `load_skill(skill_name, skill_class=MySkillClass, params)`. * * @example * ```ts * const [ok, err] = await manager.loadSkill(MyCustomSkill, { api_key: 'secret' }); * if (!ok) console.error(err); * ``` */ loadSkill(skillClass: typeof SkillBase, config?: SkillConfig): Promise<[boolean, string]>; /** * Load a skill by name from the global SkillRegistry, construct it, and add it. * This is the TypeScript equivalent of Python's `load_skill(skill_name)` path * where `skill_class=None` triggers a registry lookup. * * @param skillName - The registered skill name to look up in the SkillRegistry. * @param config - Optional configuration to pass to the skill factory. * @returns A tuple `[success, errorMessage]` matching Python's `load_skill` return * contract. `errorMessage` is an empty string on success. * * @remarks Equivalent to Python's `load_skill(skill_name)` (registry path, where * `skill_class=None`). Callers porting from Python should change * `skill_manager.load_skill(name)` → `skillManager.loadSkillByName(name)`. */ loadSkillByName(skillName: string, config?: SkillConfig): Promise<[boolean, string]>; /** * List the instance keys of all currently loaded skills. * Python equivalent: `list_loaded_skills() -> List[str]` which returns * `list(self.loaded_skills.keys())`. * * Use `listSkills()` for richer objects (name, instanceId, initialized). * Use `listSkillKeys()` for a flat list of instance key strings. * * @returns Array of instance key strings. * * @remarks Equivalent to Python's `list_loaded_skills()`. Callers porting from * Python should change `skill_manager.list_loaded_skills()` → * `skillManager.listSkillKeys()`. */ listSkillKeys(): string[]; /** * Get a skill by its instance key or instance ID. * @param keyOrId - The instance key or instance ID to look up. * @returns The skill instance, or undefined if not found. */ getSkill(keyOrId: string): SkillBase | undefined; /** * List all loaded skill instances with their name, ID, and initialization state. * @returns Array of skill summary objects. */ listSkills(): { name: string; instanceId: string; initialized: boolean; }[]; /** * Aggregate tool definitions from all loaded skills. * @returns Combined array of all skill tool definitions. */ getAllTools(): ReturnType; /** * Aggregate prompt sections from all loaded skills. * @returns Combined array of all skill prompt sections. */ getAllPromptSections(): ReturnType; /** * Aggregate speech recognition hints from all loaded skills. * @returns Combined array of all skill hint strings. */ getAllHints(): string[]; /** * Merge global data from all loaded skills into a single object. * @returns Combined global data (later skills override earlier ones on key conflicts). */ getMergedGlobalData(): Record; /** * Get the number of currently loaded skill instances. * @returns The count of loaded skills. */ get size(): number; /** * Get metadata for all loaded skills, enabling ephemeral copy re-instantiation. * @returns Array of entries containing skill name, class constructor, and config. */ getLoadedSkillEntries(): Array<{ skillName: string; SkillClass: typeof SkillBase; config: SkillConfig; }>; /** * Remove all skills and clean up. */ clear(): Promise; }