feat: skills and agents

This commit is contained in:
Gab 2026-03-24 17:59:49 +11:00
parent ff77a81141
commit 7b81c4db73
6 changed files with 31 additions and 4 deletions

View File

@ -22,6 +22,7 @@ class Region(str, Enum):
class ToolType(str, Enum): class ToolType(str, Enum):
MCP_SERVER = "mcp_server" MCP_SERVER = "mcp_server"
AGENT_SKILL = "agent_skill" AGENT_SKILL = "agent_skill"
CODER_AGENT = "coder_agent"
DATABASE_SCRIPT = "database_script" DATABASE_SCRIPT = "database_script"
API_FUNCTION = "api_function" API_FUNCTION = "api_function"

View File

@ -115,6 +115,8 @@ def parse_agent(agent) -> SyncedTool:
""" """
Parse Agent from SDK into SyncedTool. Parse Agent from SDK into SyncedTool.
Coder agents (mode='coder') are CODER_AGENT type, not skills.
Args: Args:
agent: Agent from TF SDK agent: Agent from TF SDK
@ -125,8 +127,8 @@ def parse_agent(agent) -> SyncedTool:
id=agent.id, id=agent.id,
name=agent.label or f"agent_{agent.id[:8]}", name=agent.label or f"agent_{agent.id[:8]}",
description=agent.description, description=agent.description,
tool_type=ToolType.AGENT_SKILL, tool_type=ToolType.CODER_AGENT,
is_agent_skill=True, is_agent_skill=False,
auth_via="tf_agent", auth_via="tf_agent",
) )

View File

@ -263,7 +263,7 @@ export namespace Agent {
if (!data.success || !data.tools) return [] if (!data.success || !data.tools) return []
return data.tools return data.tools
.filter((t: any) => t.tool_type === "agent_skill") .filter((t: any) => t.tool_type === "coder_agent")
.map((t: any): Info => ({ .map((t: any): Info => ({
name: t.name, name: t.name,
description: t.description, description: t.description,

View File

@ -201,7 +201,31 @@ export namespace Skill {
const all = Effect.fn("Skill.all")(function* () { const all = Effect.fn("Skill.all")(function* () {
const cache = yield* ensure() const cache = yield* ensure()
return Object.values(cache.skills) const skills = Object.values(cache.skills)
// Add TF agent skills from synced tools (only agent_skill type, not coder_agent)
const toolsPath = path.join(Global.Path.data, ".tfcode", "tools.json")
try {
const content = yield* Effect.promise(() => Bun.file(toolsPath).text())
const data = JSON.parse(content) as { success: boolean; tools: Array<{ tool_type: string; name: string; description?: string; id: string }> }
if (data.success && data.tools) {
for (const tool of data.tools) {
// Only include agent_skill (from is_agent_skill=True), not coder_agent
if (tool.tool_type === "agent_skill") {
skills.push({
name: tool.name,
description: tool.description || "ToothFairyAI Agent Skill",
location: `tf://${tool.id}`,
content: "",
})
}
}
}
} catch {
// Ignore errors loading TF tools
}
return skills
}) })
const dirs = Effect.fn("Skill.dirs")(function* () { const dirs = Effect.fn("Skill.dirs")(function* () {