( skillName: string, workspaceId: string )
| 61 | * Called when the LLM decides a skill is relevant and invokes load_skill. |
| 62 | */ |
| 63 | export async function resolveSkillContent( |
| 64 | skillName: string, |
| 65 | workspaceId: string |
| 66 | ): Promise<string | null> { |
| 67 | if (!skillName || !workspaceId) return null |
| 68 | |
| 69 | const builtin = getBuiltinSkillByName(skillName) |
| 70 | if (builtin) return builtin.content |
| 71 | |
| 72 | try { |
| 73 | const rows = await db |
| 74 | .select({ content: skill.content, name: skill.name }) |
| 75 | .from(skill) |
| 76 | .where(and(eq(skill.workspaceId, workspaceId), eq(skill.name, skillName))) |
| 77 | .limit(1) |
| 78 | |
| 79 | if (rows.length === 0) { |
| 80 | logger.warn('Skill not found', { skillName, workspaceId }) |
| 81 | return null |
| 82 | } |
| 83 | |
| 84 | return rows[0].content |
| 85 | } catch (error) { |
| 86 | logger.error('Failed to resolve skill content', { error, skillName, workspaceId }) |
| 87 | return null |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | export async function resolveSkillContentById( |
| 92 | skillId: string, |
no test coverage detected