Token导航 LogoToken导航TokenDH.com
效率执行命令clawhub未标认证来源可访问clear审计通过

task-interrupt任务中断

Agent Skill

task-interrupt 用于补充效率相关能力,适合在 OpenClaw 中需要让 Agent 承接效率相关任务时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

6,144

周安装

251

GitHub Stars

公开资料未说明

下载量

1,968
OpenClaw

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

MIT-0

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:task-interrupt(任务中断)
来源仓库:https://github.com/guyxlouspg/task-interrupt
安装命令:
openclaw skills install task-interrupt
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install task-interrupt

简介

管理和中断长时间运行任务,支持用户命令终止、资源清理和任务状态保存,防止任务卡死或无限执行。

SKILL.md

Task Interrupt Skill - 任务打断机制

概述

任务打断机制是一个用于控制和管理OpenClaw Agent任务执行的技能。它解决了Agent执行任务时卡住、运行时间过长或用户想中途终止的问题。

问题场景

  • Agent执行长时间任务时用户无法中断
  • 任务卡住或陷入死循环时无停止机制
  • 用户需要中途放弃当前任务
  • 需要优雅的资源清理和状态保存

核心架构

架构图

┌─────────────────────────────────────────────────────────────────────────┐
│                              飞书群聊                                    │
│                   用户发送: /stop  或  "中断"                            │
└────────────────────────────────┬────────────────────────────────────────┘
                                 │ Webhook/消息事件
                                 ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                        主 Agent (maojingli)                             │
│  ┌──────────────┐    ┌──────────────────┐    ┌───────────────────────┐ │
│  │  消息监听器  │───▶│  中断指令识别器   │───▶│  Subagent 管理器      │ │
│  │              │    │  /stop, 中断      │    │  sessions_*           │ │
│  │              │    │  cancel, abort    │    │                       │ │
│  └──────────────┘    └──────────────────┘    └───────────┬───────────┘ │
│                                                            │             │
│                          ┌─────────────────────────────────┘             │
│                          │                                                │
│                          ▼                                                │
│              ┌───────────────────────┐                                   │
│              │  中断信号发射器        │                                   │
│              │  1. 写入中断标志文件  │                                   │
│              │  2. process.kill()    │                                   │
│              └───────────────────────┘                                   │
└────────────────────────────────┬────────────────────────────────────────┘
                                 │ 中断信号 (信号量/标志文件)
                                 ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                    Subagent (maoxiami 等)                               │
│  ┌──────────────┐    ┌──────────────────┐    ┌───────────────────────┐ │
│  │ 心跳/轮询器  │───▶│  中断检测器       │───▶│  任务执行器 (可中断)   │ │
│  │ (每5秒检查)  │    │  检查标志文件    │    │  exec/tool calls      │ │
│  └──────────────┘    └──────────────────┘    └───────────┬───────────┘ │
│        ▲                                               │               │
│        │                                               ▼               │
│        │                                    ┌───────────────────────┐   │
│        │                                    │  安全停止处理器        │   │
│        │                                    │  1. 保存检查点        │   │
│        │                                    │  2. 清理临时文件      │   │
│        │                                    │  3. 释放资源          │   │
│        └────────────────────────────────────┴───────────────────────┘   │
└─────────────────────────────────────────────────────────────────────────┘

组件说明

1. 中断指令识别器(主Agent)

识别来自用户的打断指令:

  • /stop/中断/cancel/abort
  • 停止中断等关键词

2. 中断信号发射器(主Agent)

将中断信号传递给运行中的subagent:

  • 写入中断标志文件到 /tmp/agent-stop-{sessionId}.flag
  • 可选:发送 SIGINT 信号到子进程
  • 调用 sessions_kill 作为最终手段

3. 中断检测器(Subagent)

轮询检查中断标志:

  • 默认每5秒检查一次
  • 发现标志后触发安全停止流程
  • 自动清理过期标志(60秒)

4. 安全停止处理器(Subagent)

优雅停止并清理资源:

  • 保存当前检查点状态
  • 清理临时文件和连接
  • 取消定时任务
  • 清除中断标志
  • 通知主Agent

使用说明

1. 在主Agent中集成中断功能

在主Agent的消息处理流程中添加中断指令识别和发射逻辑。参考设计文档中的代码示例。

2. 在Subagent中启用中断检测

Subagent需要在启动时调用 startInterruptPolling(),并在任务关键点保存检查点 saveCheckpoint()

基本用法:

const interruptible = new InterruptibleAgent(sessionId);

// 启动中断轮询
await interruptible.startInterruptPolling();

try {
  // 保存检查点
  await interruptible.saveCheckpoint('task_start', { step: 1 });

  // 执行任务...
  await doLongRunningTask();

  // 保存检查点
  await interruptible.saveCheckpoint('task_complete', { success: true });

} catch (error) {
  if (error.message === 'INTERRUPTED') {
    // 处理被中断的情况
    console.log('任务被用户中断');
  }
} finally {
  // 停止轮询
  await interruptible.stopInterruptPolling();
}

3. 命令行工具

技能提供了三个Shell脚本用于手动测试和管理:

create-stop-flag.sh - 创建停止标志

./scripts/create-stop-flag.sh <sessionId> [reason]

示例:

./scripts/create-stop-flag.sh abc123 "User requested stop"

check-stop-flag.sh - 检查停止标志

./scripts/check-stop-flag.sh <sessionId> [maxAgeSeconds]

返回码:

  • 0: 标志存在且在有效期内
  • 1: 标志不存在或已过期

示例:

if ./scripts/check-stop-flag.sh abc123 60; then
  echo "检测到中断请求"
fi

clear-stop-flag.sh - 清除停止标志

./scripts/clear-stop-flag.sh <sessionId>

示例:

./scripts/clear-stop-flag.sh abc123

API 参考

InterruptibleAgent 类

属性

属性类型描述
sessionIdstring当前会话ID
interruptCheckIntervalnumber轮询间隔(毫秒,默认5000)
isInterruptedboolean是否已中断
checkpointsArray已保存的检查点列表

方法

startInterruptPolling()

启动中断检测轮询。

await agent.startInterruptPolling();

stopInterruptPolling()

停止中断检测轮询。

await agent.stopInterruptPolling();

checkForInterrupt()

手动检查中断标志(通常自动调用)。

const flag = await agent.checkForInterrupt();
// 返回 null 或 { sessionId, reason, timestamp, signal }

saveCheckpoint(name, data)

保存任务检查点。

await agent.saveCheckpoint('step1', { processed: 100, total: 200 });

getLastCheckpoint()

获取最后一个检查点。

const checkpoint = agent.getLastCheckpoint();

handleInterrupt(flag)

处理中断(内部调用)。

await agent.handleInterrupt(flag);

SafeStopHandler 类

提供安全停止和资源清理功能。

方法

stop(reason)

执行完整的安全停止流程。

const handler = new SafeStopHandler(agent);
const result = await handler.stop('user_stop');
// 返回 { success: boolean, checkpoint?: object, reason?: string, error?: string }

saveState()

保存Agent状态到 /tmp/agent-state/{sessionId}.json

const statePath = await handler.saveState();

cleanupTempFiles()

清理临时文件模式:

  • /tmp/agent-work/{sessionId}/*
  • /tmp/agent-downloads/{sessionId}/*
await handler.cleanupTempFiles();

closeConnections()

关闭数据库连接和文件句柄。

await handler.closeConnections();

cancelScheduledTasks()

取消所有定时任务。

await handler.cancelScheduledTasks();

文件结构

task-interrupt/
├── SKILL.md                 # 本文档
├── instructions.md          # Agent指令说明
├── claw.json                # 技能元数据
└── scripts/
    ├── create-stop-flag.sh  # 创建停止标志
    ├── check-stop-flag.sh   # 检查停止标志
    └── clear-stop-flag.sh   # 清除停止标志

文件路径规范

中断标志文件:/tmp/agent-stop-{sessionId}.flag

状态保存文件:/tmp/agent-state/{sessionId}.json

标志文件格式:

{
  "sessionId": "abc123",
  "timestamp": 1742345678901,
  "reason": "user_request",
  "signal": "SIGINT"
}

配置选项

可通过环境变量调整行为:

变量默认值说明
INTERRUPT_CHECK_INTERVAL5000轮询间隔(毫秒)
INTERRUPT_FLAG_DIR/tmp/agent-stop标志文件目录
INTERRUPT_FLAG_MAX_AGE60标志最大有效期(秒)
AGENT_STATE_DIR/tmp/agent-state状态保存目录

安全考虑

  • 中断标志文件应具有适当权限(0600)
  • 只允许删除自己session的标志文件
  • 状态文件可能包含敏感数据,应定期清理
  • 清理资源时应确保连接正确关闭

故障排除

中断没有生效

  1. 检查Subagent是否已启动轮询:startInterruptPolling()
  2. 确认标志文件路径是否正确:/tmp/agent-stop-{sessionId}.flag
  3. 检查轮询间隔是否过短或过长

中断后资源未释放

  1. 检查 safeStopHandler.stop() 是否完整执行
  2. 确认数据库连接和文件句柄是否全部关闭
  3. 查看临时文件是否已清理

标志文件未自动清除

  1. 检查文件权限
  2. 确认 clear-stop-flag.sh 是否执行成功
  3. 标志文件60秒后自动过期

示例:完整集成

// interruptible-agent.js
const path = require('path');
const { exec } = require('child_process');

class InterruptibleAgent {
  constructor(sessionId, options = {}) {
    this.sessionId = sessionId;
    this.interruptCheckInterval = options.interval || 5000;
    this.isInterrupted = false;
    this.checkpoints = [];
    this.pollingTimer = null;
  }

  startInterruptPolling() {
    this.pollingTimer = setInterval(async () => {
      await this.checkForInterrupt();
    }, this.interruptCheckInterval);
  }

  stopInterruptPolling() {
    if (this.pollingTimer) {
      clearInterval(this.pollingTimer);
      this.pollingTimer = null;
    }
  }

  async checkForInterrupt() {
    try {
      const flagPath = `/tmp/agent-stop-${this.sessionId}.flag`;
      if (await fs.pathExists(flagPath)) {
        const content = await fs.readFile(flagPath, 'utf8');
        const flag = JSON.parse(content);

        console.log(`[中断] 检测到中断信号: ${flag.reason}`);
        this.isInterrupted = true;
        await this.handleInterrupt(flag);
      }
    } catch (error) {
      console.error(`[中断] 检查失败: ${error.message}`);
    }
  }

  saveCheckpoint(name, data) {
    const checkpoint = {
      name,
      data,
      timestamp: Date.now()
    };
    this.checkpoints.push(checkpoint);
    console.log(`[检查点] 已保存: ${name}`);
  }

  getLastCheckpoint() {
    return this.checkpoints[this.checkpoints.length - 1] || null;
  }

  async handleInterrupt(flag) {
    console.log('[中断] 开始安全停止流程...');

    this.stopInterruptPolling();
    await this.saveState();
    await this.cleanup();
    await this.clearFlag(flag);

    // 通知主Agent
    await this.notifyMainAgent({
      interrupted: true,
      checkpoint: this.getLastCheckpoint(),
      reason: flag.reason
    });
  }

  async clearFlag(flag) {
    const flagPath = `/tmp/agent-stop-${flag.sessionId}.flag`;
    if (await fs.pathExists(flagPath)) {
      await fs.remove(flagPath);
    }
  }

  async saveState() {
    const state = {
      sessionId: this.sessionId,
      checkpoints: this.checkpoints,
      timestamp: Date.now()
    };
    const stateDir = '/tmp/agent-state';
    await fs.ensureDir(stateDir);
    await fs.writeJson(path.join(stateDir, `${this.sessionId}.json`), state);
    console.log(`[状态] 已保存`);
  }

  async cleanup() {
    // 清理临时文件
    const tempDir = `/tmp/agent-work/${this.sessionId}`;
    if (await fs.pathExists(tempDir)) {
      await fs.remove(tempDir);
    }

    // 关闭连接
    if (this.db) await this.db.end();
    if (this.fileHandles) {
      for (const fh of this.fileHandles) {
        await fh.close();
      }
    }

    // 取消定时任务
    if (this.schedules) {
      for (const s of this.schedules) {
        clearTimeout(s.timer);
        clearInterval(s.interval);
      }
    }

    console.log('[清理] 完成');
  }

  async notifyMainAgent(result) {
    // 实现通知逻辑
    console.log('[通知]', result);
  }
}

module.exports = InterruptibleAgent;

性能影响

  • 轮询间隔建议5-10秒
  • 检查点保存频率根据任务重要性调整
  • 状态保存使用异步IO,避免阻塞任务执行

测试

提供测试脚本验证功能:

# 测试1: 创建标志
./scripts/create-stop-flag.sh test-session "test reason"

# 测试2: 检查标志
./scripts/check-stop-flag.sh test-session 60

# 测试3: 清除标志
./scripts/clear-stop-flag.sh test-session

版本历史

  • 1.0.0 - 初始版本

- 基础中断标志文件机制 - 轮询检测(5秒间隔) - 安全停止流程 - Shell命令行工具

相关链接

贡献

欢迎提交 Issue 和 Pull Request!

许可证

MIT

适合场景

01

OpenClaw 用户查找和安装 Skill 时

02

用户想查找某类 Agent Skill 时

03

需要根据任务场景推荐可安装能力包时

04

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

OpenClaw

85.02%
按下载量换算1,673

安全审计

VirusTotal

通过

ClawScan

通过

Static analysis

通过

权限和风险

执行命令

安装流程涉及命令执行,可能通过 openclaw skills install task-interrupt 联网下载 Skill 或依赖。用户安装前应确认命令来源、仓库内容和执行环境。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills