feat: Add skill creation command (#141)

Co-authored-by: cpacker <packercharles@gmail.com>
Co-authored-by: Sarah Wooders <sarahwooders@gmail.com>
This commit is contained in:
Kevin Lin
2025-12-01 21:02:49 -08:00
committed by GitHub
parent 8ce6d32087
commit 57169c63e1
14 changed files with 1482 additions and 11 deletions

View File

@@ -901,26 +901,28 @@ export default function App({
// Handle commands (messages starting with "/")
if (msg.startsWith("/")) {
const trimmed = msg.trim();
// Special handling for /model command - opens selector
if (msg.trim() === "/model") {
if (trimmed === "/model") {
setModelSelectorOpen(true);
return { submitted: true };
}
// Special handling for /toolset command - opens selector
if (msg.trim() === "/toolset") {
if (trimmed === "/toolset") {
setToolsetSelectorOpen(true);
return { submitted: true };
}
// Special handling for /system command - opens system prompt selector
if (msg.trim() === "/system") {
if (trimmed === "/system") {
setSystemPromptSelectorOpen(true);
return { submitted: true };
}
// Special handling for /agent command - show agent link
if (msg.trim() === "/agent") {
if (trimmed === "/agent") {
const cmdId = uid("cmd");
const agentUrl = `https://app.letta.com/projects/default-project/agents/${agentId}`;
buffersRef.current.byId.set(cmdId, {
@@ -937,13 +939,13 @@ export default function App({
}
// Special handling for /exit command - show stats and exit
if (msg.trim() === "/exit") {
if (trimmed === "/exit") {
handleExit();
return { submitted: true };
}
// Special handling for /logout command - clear credentials and exit
if (msg.trim() === "/logout") {
if (trimmed === "/logout") {
const cmdId = uid("cmd");
buffersRef.current.byId.set(cmdId, {
kind: "command",
@@ -1451,8 +1453,84 @@ export default function App({
return { submitted: true };
}
// Special handling for /skill command - enter skill creation mode
if (trimmed.startsWith("/skill")) {
const cmdId = uid("cmd");
// Extract optional description after `/skill`
const [, ...rest] = trimmed.split(/\s+/);
const description = rest.join(" ").trim();
const initialOutput = description
? `Starting skill creation for: ${description}`
: "Starting skill creation. Ill load the skill-creator skill and ask a few questions about the skill you want to build...";
buffersRef.current.byId.set(cmdId, {
kind: "command",
id: cmdId,
input: msg,
output: initialOutput,
phase: "running",
});
buffersRef.current.order.push(cmdId);
refreshDerived();
setCommandRunning(true);
try {
// Import the skill-creation prompt
const { SKILL_CREATOR_PROMPT } = await import(
"../agent/promptAssets.js"
);
// Build system-reminder content for skill creation
const userDescriptionLine = description
? `\n\nUser-provided skill description:\n${description}`
: "\n\nThe user did not provide a description with /skill. Ask what kind of skill they want to create before proceeding.";
const skillMessage = `<system-reminder>\n${SKILL_CREATOR_PROMPT}${userDescriptionLine}\n</system-reminder>`;
// Mark command as finished before sending message
buffersRef.current.byId.set(cmdId, {
kind: "command",
id: cmdId,
input: msg,
output:
"Entered skill creation mode. Answer the assistants questions to design your new skill.",
phase: "finished",
success: true,
});
refreshDerived();
// Process conversation with the skill-creation prompt
await processConversation([
{
type: "message",
role: "user",
content: skillMessage,
},
]);
} catch (error) {
buffersRef.current.byId.set(cmdId, {
kind: "command",
id: cmdId,
input: msg,
output: `Failed: ${
error instanceof Error ? error.message : String(error)
}`,
phase: "finished",
success: false,
});
refreshDerived();
} finally {
setCommandRunning(false);
}
return { submitted: true };
}
// Special handling for /init command - initialize agent memory
if (msg.trim() === "/init") {
if (trimmed === "/init") {
const cmdId = uid("cmd");
buffersRef.current.byId.set(cmdId, {
kind: "command",

View File

@@ -113,6 +113,13 @@ export const commands: Record<string, Command> = {
return "Initializing memory...";
},
},
"/skill": {
desc: "Enter skill creation mode (optionally: /skill <description>)",
handler: () => {
// Handled specially in App.tsx to trigger skill-creation workflow
return "Starting skill creation...";
},
},
};
/**