关于 action-creator
用于编写 TypeScript Action 模板的技能,将用户特定的邮件流程定义为可复用操作,并以聊天界面的按钮触发。适合需要自动化重复邮件任务或建立个性化邮件管理流程的用户。
主要功能
- 01生成 TypeScript Action 模板
- 02定义操作参数与元数据
- 03通过上下文方法处理邮件
- 04支持 AI 分析和后续操作
- 05返回执行结果并提供错误处理
适用场景
- 01创建特定客户的付款提醒操作
- 02将问题邮件转发给工程团队
- 03归档指定来源的新闻邮件
- 04在聊天中触发重复邮件流程
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ anthropics/ claude-agent-sdk-demos --skill action-creator安装后在 Claude Code 中输入/action-creator确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
templates/archive-old-newsletters.tsforward-bug-report.tssend-payment-reminder.ts详细介绍
Action 创建器
创建 TypeScript 操作模板文件,用于定义可重复使用、面向特定用户的操作,用户可以在聊天界面中单击一次即可执行。
何时使用此技能
当用户想要:
- 为特定工作流创建可重复使用的操作(“我经常需要向 ACME Corp 发送付款提醒”)
- 为供应商/客户设置一键操作(“将错误转发给工程团队”)
- 使用特定上下文自动处理重复性电子邮件任务(“归档来自 TechCrunch/Morning Brew 的新闻简报”)
- 为业务流程构建个性化的电子邮件管理工具
与监听器的主要区别:操作由用户触发(在聊天中单击),监听器则由事件触发(自动执行)。
操作的工作方式
操作是位于 agent/custom_scripts/actions/ 中的 TypeScript 文件,文件会:
- 导出一个
config对象,用于定义模板元数据和参数架构 - 导出一个
handler函数,用于使用给定参数执行操作 - 使用
ActionContext方法执行操作(电子邮件 API、发送电子邮件、调用 AI 等)
Agent 会在对话期间通过提供特定参数来创建操作实例,这些实例会以可单击按钮的形式显示在聊天中。
创建操作模板
1. 了解特定用户的工作流
解析用户的请求,确定:
- 用户上下文:他们有哪些特定的供应商/客户/团队?
- 操作:他们需要执行什么具体操作?(发送给 ACME Corp、转发给工程团队等)
- 参数:每次执行时哪些内容会变化?(发票编号、优先级、存放天数)
- 频率:他们会多久使用一次?
2. 编写操作模板文件
在 agent/custom_scripts/actions/ 中创建文件,并采用以下结构:
import type { ActionTemplate, ActionContext, ActionResult } from "../types";
export const config: ActionTemplate = {
id: "unique_action_id", // kebab-case, user-specific
name: "Human Readable Name", // For UI display
description: "What this action does", // Explain the operation
icon: "📨", // Optional emoji icon
parameterSchema: {
type: "object",
properties: {
paramName: {
type: "string", // or "number", "boolean"
description: "Parameter description",
enum: ["option1", "option2"], // Optional: restrict values
default: "defaultValue" // Optional: default value
}
},
required: ["paramName"] // List required parameters
}
};
export async function handler(
params: Record<string, any>,
context: ActionContext
): Promise<ActionResult> {
const { paramName } = params;
context.log(`Starting action: ${config.name}`);
try {
// 1. Perform operations using context methods
// 2. Use AI for intelligent processing if needed
// 3. Update emails, send emails, etc.
context.notify("Action completed successfully", {
type: "success",
priority: "normal"
});
return {
success: true,
message: "Action completed successfully",
data: { /* optional structured data */ },
refreshInbox: true // Optional: refresh inbox after action
};
} catch (error: any) {
context.log(`Action failed: ${error}`, "error");
return {
success: false,
message: `Failed: ${error.message}`
};
}
}
3. 文件命名约定
使用能体现特定用户操作的 kebab-case 名称:
send-payment-reminder-to-acme.ts(而不是send-email.ts)forward-bugs-to-engineering.ts(而不是forward-email.ts)archive-newsletters-from-techcrunch.ts(而不是archive-emails.ts)summarize-weekly-updates-from-ceo.ts(而不是summarize-emails.ts)
重要:模板应针对用户实际使用的工作流、供应商、团队和流程。
4. 可用的上下文方法
ActionContext 提供以下功能:
// Email API operations
const emails = await context.emailAPI.getInbox({ limit: 30, includeRead: false });
const results = await context.emailAPI.searchEmails({ from: "[email protected]" });
const results = await context.emailAPI.searchWithGmailQuery("from:sender after:2024/01/01");
const emails = await context.emailAPI.getEmailsByIds(["id1", "id2"]);
const email = await context.emailAPI.getEmailById("email-id");
// Direct email operations
await context.archiveEmail(emailId);
await context.starEmail(emailId);
await context.unstarEmail(emailId);
await context.markAsRead(emailId);
await context.markAsUnread(emailId);
await context.addLabel(emailId, "label-name");
await context.removeLabel(emailId, "label-name");
// Send emails
const result = await context.sendEmail({
to: "[email protected]",
subject: "Email subject",
body: "Email body content",
cc: "[email protected]", // Optional
bcc: "[email protected]", // Optional
replyTo: "[email protected]" // Optional
});
// AI-powered processing
const analysis = await context.callAgent<ResultType>({
prompt: "Analyze this email and extract key info...",
systemPrompt: "You are an expert at...", // Optional
tools: ["Read", "WebSearch"], // Optional
maxTokens: 2000 // Optional
});
// Session messaging (inject into chat)
context.addUserMessage("User said this");
context.addAssistantMessage("Assistant responds");
context.addSystemMessage("System notification");
// Notifications
context.notify("Operation completed", {
priority: "high" | "normal" | "low",
type: "info" | "success" | "warning" | "error"
});
// External API access
const response = await context.fetch("https://api.example.com/data");
const data = await response.json();
// Logging (visible in server logs)
context.log("Info message", "info");
context.log("Warning message", "warn");
context.log("Error message", "error");
操作结果
始终返回 ActionResult 对象:
return {
success: true, // Required: boolean
message: "Human-readable result", // Required: string
data: { key: "value" }, // Optional: structured data
suggestedActions: [], // Optional: follow-up actions
refreshInbox: true // Optional: refresh inbox
};
示例和模板
常见模式可参考以下模板文件:
- send-payment-reminder.ts:向特定供应商发送发票提醒
- forward-bug-report.ts:通过 AI 分析将错误转发给工程团队
- archive-old-newsletters.ts:归档来自特定来源的新闻简报
最佳实践
- 特定用户的模板:创建针对用户实际使用的供应商、客户、团队和流程的模板
- 描述性命名:使用体现具体操作的名称(避免使用“send-email”这类通用名称)
- 丰富的参数架构:定义清晰的参数类型及其说明
- AI 驱动:使用
context.callAgent()进行智能处理 - 错误处理:始终使用 try-catch 包装操作,并返回有意义的错误信息
- 清晰的消息:返回易于理解的成功/失败消息
- 幂等性:尽可能将处理函数设计为可安全重复运行
- 日志记录:使用
context.log()进行调试和记录审计轨迹
参数架构指南
使用 JSON Schema 定义参数:
parameterSchema: {
type: "object",
properties: {
// String parameter
emailId: {
type: "string",
description: "Email ID to process"
},
// Number parameter with default
daysOld: {
type: "number",
description: "Number of days old",
default: 30
},
// Enum parameter (dropdown)
priority: {
type: "string",
description: "Priority level",
enum: ["P0 - Critical", "P1 - High", "P2 - Medium", "P3 - Low"]
},
// Boolean parameter
sendNotification: {
type: "boolean",
description: "Send notification when complete"
}
},
required: ["emailId", "priority"] // List required params
}
创建文件
当用户请求创建操作模板时:
-
明确用户特定的上下文:
- 他们的供应商、客户或团队有哪些?
- 他们的具体工作流是什么?
- 每次执行时哪些参数会变化?
-
在
agent/custom_scripts/actions/中编写 TypeScript 文件 -
使用 Write 工具创建文件,并包含:
- 从 "../types" 导入正确的类型
- 用户特定的配置(而非通用配置)
- 包含所有必需字段的参数架构
- 包含错误处理的处理器
- 清晰的成功/失败消息
-
测试参数:确保定义了所有必需参数
-
向用户确认此操作符合其工作流
常见模式
1. 向特定收件人发送电子邮件
用户特定内容 → 使用模板撰写电子邮件 → 发送 → 返回结果
const body = `Hi ${recipientName},
Your invoice ${invoiceNumber} for ${amount} is ${daysPastDue} days past due...`;
await context.sendEmail({
to: "[email protected]",
subject: `Payment Reminder: Invoice ${invoiceNumber}`,
body
});
2. 批量电子邮件操作
搜索电子邮件 → 筛选 → 对每封邮件执行操作 → 返回数量
const emails = await context.emailAPI.searchWithGmailQuery(query);
for (const email of emails) {
await context.archiveEmail(email.messageId);
}
return { success: true, message: `Archived ${emails.length} emails` };
3. AI 驱动的电子邮件处理
获取电子邮件 → 调用 AI 进行分析 → 使用 AI 结果 → 执行操作 → 返回摘要
const email = await context.emailAPI.getEmailById(emailId);
const analysis = await context.callAgent({
prompt: `Analyze this bug report: ${email.body}...`,
maxTokens: 1000
});
await context.sendEmail({ to: "[email protected]", ... });
4. 增强型电子邮件转发
获取电子邮件 → AI 分析 → 撰写增强版转发邮件 → 发送 → 为原邮件添加标签
const email = await context.emailAPI.getEmailById(emailId);
const analysis = await context.callAgent({ /* analyze */ });
await context.sendEmail({
to: "[email protected]",
subject: `[${priority}] ${email.subject}`,
body: `AI Analysis:\n${analysis}\n\nOriginal:\n${email.body}`
});
await context.addLabel(emailId, "FORWARDED");
类型导入
始终从正确的位置导入类型:
import type { ActionTemplate, ActionContext, ActionResult } from "../types";
// ActionTemplate: Template metadata and parameter schema
// ActionContext: Runtime context with all capabilities
// ActionResult: Return type for handler function
用户如何触发操作
创建操作模板后:
- Agent 发现模板:在对话过程中,Agent 会读取可用操作
- Agent 创建实例:Agent 会根据用户的具体情况提供参数
- 用户看到按钮:操作实例会以可点击按钮的形式显示在聊天中
- 用户点击:操作会使用预填参数执行
- 显示结果:聊天中会显示成功/失败消息
示例流程:
User: "I need to follow up on the ACME invoice"
Agent: [searches emails, finds Invoice #2024-001 is 15 days overdue]
Agent: Creates action instance with parameters:
{
templateId: "send_payment_reminder_acme",
params: { invoiceNumber: "INV-2024-001", amount: "$5,000", daysPastDue: 15 }
}
User: [sees button "Send payment reminder to ACME Corp for Invoice #2024-001"]
User: [clicks button]
Action: Executes, sends email, returns "Payment reminder sent to ACME Corp"
参考
完整规范:请参阅项目根目录中的 ACTIONS_SPEC.md,了解以下内容的完整详情:
- 完整的类型定义
- ActionsManager 实现
- WebSocket 协议
- 前端集成
- 高级示例
- 日志记录和审计跟踪