Skill: rfdiosuao/context-usage-checker (version 1.0.0)

# Context Usage Checker - 上下文使用率查询 Skill ## 🎯 功能 查询当前会话的上下文（Token）使用情况，包括： - 已使用的 Token 数量 - 剩余 Token 数量 - 使用率百分比 - 进度条可视化 - 智能建议（超过阈值时提醒） ## 🚀 使用方法 ### 方式 1：直接对话 ``` 查一下上下文使用率 看看 token 用了多少 上下文还剩多少 ``` ### 方式 2：使用命令 ``` /context /ctx /tokens /usage ``` ## 📊 输出示例 ### 正常状态（35%） ``` ### 📊 上下文使用状态 **状态：** 正常 **模型：** qwen3.5-plus **使用率：** 35.2% `▓▓▓▓▓▓▓░░░░░░░░░░░░` **已使用：** 90,112 tokens **剩余：** 165,888 tokens **总计：** 256,000 tokens > ✅ 上下文使用正常，可以继续对话 ``` ### 警告状态（78%） ``` ### ⚠️ 上下文使用状态 **状态：** 警告 **模型：** qwen3.5-plus **使用率：** 78.5% `▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░` **已使用：** 200,960 tokens **剩余：** 55,040 tokens **总计：** 256,000 tokens > 💡 **建议：** 使用 `/new` 开启新会话 或 `/compact` 压缩上下文 ``` ### 严重警告（92%） ``` ### 🚨 上下文使用状态 **状态：** 严重 **模型：** qwen3.5-plus **使用率：** 92.3% `▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░` **已使用：** 236,288 tokens **剩余：** 19,712 tokens **总计：** 256,000 tokens > 🚨 **严重警告：** 上下文即将超限！建议立即使用 `/new` 开启新会话 ``` ## ⚙️ 配置 ### 阈值设置 - **警告阈值：** 70%（显示⚠️） - **严重阈值：** 90%（显示🚨） ### 支持的模型 自动识别以下模型的上下文窗口： - `qwen3.5-plus`: 256,000 tokens - `qwen3.5`: 256,000 tokens - `qwen-max`: 32,000 tokens - 其他模型：默认 128,000 tokens ## 🔧 技术原理 ### Token 估算算法 ``` 中文字符：约 1.5 字符/token 英文字符：约 4 字符/token ``` ### 进度条生成 - 总长度：20 个字符 - 已使用：▓ - 剩余：░ ## 📝 注意事项 1. **估算误差：** Token 计算为估算值，实际以平台统计为准（误差±10%） 2. **会话范围：** 仅统计当前会话的历史消息 3. **性能影响：** 每次查询耗时 < 10ms ## 🐛 常见问题 **Q: 为什么显示的 Token 数和平台不一致？** A: 本 Skill 使用字符数估算算法，实际 Token 数以平台为准。 **Q: 可以修改阈值吗？** A: 可以在 Skill 代码中修改 `WARNING_THRESHOLD` 和 `CRITICAL_THRESHOLD` 常量。 **Q: 支持哪些平台？** A: 支持所有 OpenClaw 集成的平台（飞书、Telegram、WhatsApp 等）。 ## 📄 许可证 MIT License ## 🔗 相关链接 - [OpenClaw 文档](https://docs.openclaw.ai) - [ClawHub](https://clawhub.ai) - [GitHub 仓库](https://github.com/rfdiosuao/openclaw-skills) --- **作者：** Spark **版本：** 1.0.0 **最后更新：** 2026-04-06

path: README.md
content: # Context Usage Checker - 上下文使用率查询 Skill

快速查询当前会话的 Token 使用情况，支持进度条可视化和智能预警。

## 🚀 快速开始

### 安装
```bash
claw skill install context-usage-checker
```

### 使用
直接对话：
```
查一下上下文使用率
看看 token 用了多少
```

## ✨ 功能特性

- 📊 实时查询 Token 使用情况
- 📈 进度条可视化展示
- ⚠️ 智能预警（70%/90% 阈值）
- 🎯 支持多种模型
- ⚡ 快速响应（<10ms）

## 📖 详细文档

查看 [SKILL.md](./SKILL.md) 获取完整文档。

## 📄 许可证

MIT License

---

**作者：** Spark  
**版本：** 1.0.0


path: dist/index.d.ts
content: /**
 * Context Usage Checker - 上下文使用率查询 Skill
 *
 * 查询当前会话的 Token 使用情况，提供进度条可视化和智能预警
 *
 * @author Spark
 * @version 1.0.0
 */
declare const MODEL_LIMITS: Record<string, number>;
declare const WARNING_THRESHOLD = 70;
declare const CRITICAL_THRESHOLD = 90;
/**
 * 估算文本的 token 数量
 * 中文约 1.5 字符/token，英文约 4 字符/token
 */
declare function estimateTokens(text: string): number;
/**
 * 生成进度条
 * @param percentage 百分比 (0-100)
 * @param length 进度条长度 (默认 20)
 */
declare function generateProgressBar(percentage: number, length?: number): string;
/**
 * 格式化数字（添加千位分隔符）
 */
declare function formatNumber(num: number): string;
/**
 * 获取模型的上下文窗口限制
 */
declare function getModelContextLimit(modelName: string): number;
/**
 * 计算会话的 token 使用统计
 */
declare function calculateTokenStats(sessionHistory: any[], modelName: string): {
    used: number;
    limit: number;
    percentage: number;
    remaining: number;
};
/**
 * 生成上下文状态消息
 */
declare function generateStatusMessage(stats: any, modelName: string): string;
/**
 * Skill 主函数
 */
export default function contextUsageChecker(params: any): Promise<void>;
export { estimateTokens, generateProgressBar, formatNumber, getModelContextLimit, calculateTokenStats, generateStatusMessage, MODEL_LIMITS, WARNING_THRESHOLD, CRITICAL_THRESHOLD, };
//# sourceMappingURL=index.d.ts.map

path: dist/index.js
content: /**
 * Context Usage Checker - 上下文使用率查询 Skill
 *
 * 查询当前会话的 Token 使用情况，提供进度条可视化和智能预警
 *
 * @author Spark
 * @version 1.0.0
 */
// 模型上下文窗口限制
const MODEL_LIMITS = {
    'qwen3.5-plus': 256000,
    'qwen3.5': 256000,
    'qwen-max': 32000,
    'qwen-plus': 32000,
    'claude-3-5-sonnet': 200000,
    'claude-3-opus': 200000,
    'claude-3-sonnet': 200000,
    'claude-3-haiku': 200000,
    'gpt-4-turbo': 128000,
    'gpt-4': 128000,
    'gpt-4o': 128000,
    'gpt-3.5-turbo': 16385,
    'gemini-pro': 128000,
    'llama-3-70b': 8192,
    'default': 128000,
};
// 阈值配置
const WARNING_THRESHOLD = 70; // 警告阈值（%）
const CRITICAL_THRESHOLD = 90; // 严重警告阈值（%）
/**
 * 估算文本的 token 数量
 * 中文约 1.5 字符/token，英文约 4 字符/token
 */
function estimateTokens(text) {
    if (!text)
        return 0;
    const chineseChars = (text.match(/[\u4e00-\u9fa5]/g) || []).length;
    const englishChars = text.length - chineseChars;
    return Math.round(chineseChars / 1.5 + englishChars / 4);
}
/**
 * 生成进度条
 * @param percentage 百分比 (0-100)
 * @param length 进度条长度 (默认 20)
 */
function generateProgressBar(percentage, length = 20) {
    const filled = Math.round((percentage / 100) * length);
    return '▓'.repeat(filled) + '░'.repeat(length - filled);
}
/**
 * 格式化数字（添加千位分隔符）
 */
function formatNumber(num) {
    return num.toLocaleString();
}
/**
 * 获取模型的上下文窗口限制
 */
function getModelContextLimit(modelName) {
    if (!modelName)
        return MODEL_LIMITS.default;
    if (MODEL_LIMITS[modelName])
        return MODEL_LIMITS[modelName];
    // 模糊匹配
    for (const [key, limit] of Object.entries(MODEL_LIMITS)) {
        if (modelName.toLowerCase().includes(key))
            return limit;
    }
    return MODEL_LIMITS.default;
}
/**
 * 计算会话的 token 使用统计
 */
function calculateTokenStats(sessionHistory, modelName) {
    const limit = getModelContextLimit(modelName);
    let usedTokens = 0;
    for (const message of sessionHistory) {
        if (message.content) {
            usedTokens += estimateTokens(message.content);
        }
        if (message.tool_calls) {
            for (const tool of message.tool_calls) {
                usedTokens += estimateTokens(JSON.stringify(tool));
            }
        }
    }
    const percentage = Math.min((usedTokens / limit) * 100, 100);
    const remaining = limit - usedTokens;
    return {
        used: usedTokens,
        limit,
        percentage,
        remaining,
    };
}
/**
 * 生成上下文状态消息
 */
function generateStatusMessage(stats, modelName) {
    const { percentage, used, limit, remaining } = stats;
    let icon = '📊';
    let statusText = '正常';
    let advice = '> ✅ 上下文使用正常，可以继续对话';
    if (percentage >= CRITICAL_THRESHOLD) {
        icon = '🚨';
        statusText = '严重';
        advice = '> 🚨 **严重警告：** 上下文即将超限！建议立即使用 `/new` 开启新会话';
    }
    else if (percentage >= WARNING_THRESHOLD) {
        icon = '⚠️';
        statusText = '警告';
        advice = '> 💡 **建议：** 使用 `/new` 开启新会话 或 `/compact` 压缩上下文';
    }
    else if (percentage >= 50) {
        advice = '> ✅ 上下文使用正常，可以继续对话';
    }
    const progressBar = generateProgressBar(percentage);
    let message = `### ${icon} 上下文使用状态\n\n`;
    message += `**状态：** ${statusText}\n`;
    message += `**模型：** ${modelName}\n\n`;
    message += `**使用率：** ${percentage.toFixed(1)}%\n`;
    message += `\`${progressBar}\`\n\n`;
    message += `**已使用：** ${formatNumber(used)} tokens\n`;
    message += `**剩余：** ${formatNumber(remaining)} tokens\n`;
    message += `**总计：** ${formatNumber(limit)} tokens\n\n`;
    message += advice;
    return message;
}
/**
 * Skill 主函数
 */
export default async function contextUsageChecker(params) {
    const { runtime, reply } = params;
    try {
        // 获取当前会话历史
        const sessionHistory = runtime?.session?.history || [];
        const modelName = runtime?.agent?.model?.id || 'qwen3.5-plus';
        // 计算 token 使用统计
        const stats = calculateTokenStats(sessionHistory, modelName);
        // 生成状态消息
        const statusMessage = generateStatusMessage(stats, modelName);
        // 回复用户
        await reply({ text: statusMessage });
    }
    catch (error) {
        // 错误处理
        const errorMessage = `### ❌ 查询失败\n\n无法获取上下文使用率：${error instanceof Error ? error.message : String(error)}\n\n请重试或联系管理员。`;
        await reply({ text: errorMessage });
    }
}
// 导出工具函数供其他模块使用
export { estimateTokens, generateProgressBar, formatNumber, getModelContextLimit, calculateTokenStats, generateStatusMessage, MODEL_LIMITS, WARNING_THRESHOLD, CRITICAL_THRESHOLD, };
//# sourceMappingURL=index.js.map

path: package-lock.json
content: {
  "name": "context-usage-checker",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "context-usage-checker",
      "version": "1.0.0",
      "license": "MIT",
      "devDependencies": {
        "@types/node": "^20.0.0",
        "typescript": "^5.0.0"
      }
    },
    "node_modules/@types/node": {
      "version": "20.19.39",
      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.39.tgz",
      "integrity": [REDACTED_SECRET],
      "dev": true,
      "license": "MIT",
      "dependencies": {
        "undici-types": "~6.21.0"
      }
    },
    "node_modules/typescript": {
      "version": "5.9.3",
      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
      "integrity": [REDACTED_SECRET],
      "dev": true,
      "license": "Apache-2.0",
      "bin": {
        "tsc": "bin/tsc",
        "tsserver": "bin/tsserver"
      },
      "engines": {
        "node": ">=14.17"
      }
    },
    "node_modules/undici-types": {
      "version": "6.21.0",
      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
      "integrity": [REDACTED_SECRET],
      "dev": true,
      "license": "MIT"
    }
  }
}


path: package.json
content: {
  "name": "context-usage-checker",
  "version": "1.0.0",
  "description": "查询当前会话的上下文（Token）使用率",
  "type": "module",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "scripts": {
    "build": "tsc",
    "watch": "tsc --watch"
  },
  "keywords": [
    "context",
    "token",
    "usage",
    "monitor"
  ],
  "author": "Spark",
  "license": "MIT",
  "devDependencies": {
    "@types/node": "^20.0.0",
    "typescript": "^5.0.0"
  }
}


path: skill.json
content: {
  "name": "context-usage-checker",
  "version": "1.0.0",
  "description": "查询当前会话的上下文（Token）使用率，支持进度条可视化和智能预警",
  "author": "Spark",
  "license": "MIT",
  "keywords": [
    "context",
    "token",
    "usage",
    "monitor",
    "会话",
    "上下文"
  ],
  "category": "utilities",
  "main": "src/index.ts",
  "scripts": {
    "build": "tsc",
    "test": "node --test tests/*.test.js"
  },
  "engines": {
    "node": ">=18.0.0"
  },
  "dependencies": {},
  "devDependencies": {
    "@types/node": "^20.0.0",
    "typescript": "^5.0.0"
  }
}


path: src/index.ts
content: /**
 * Context Usage Checker - 上下文使用率查询 Skill
 * 
 * 查询当前会话的 Token 使用情况，提供进度条可视化和智能预警
 * 
 * @author Spark
 * @version 1.0.0
 */

// 模型上下文窗口限制
const MODEL_LIMITS: Record<string, number> = {
  'qwen3.5-plus': 256000,
  'qwen3.5': 256000,
  'qwen-max': 32000,
  'qwen-plus': 32000,
  'claude-3-5-sonnet': 200000,
  'claude-3-opus': 200000,
  'claude-3-sonnet': 200000,
  'claude-3-haiku': 200000,
  'gpt-4-turbo': 128000,
  'gpt-4': 128000,
  'gpt-4o': 128000,
  'gpt-3.5-turbo': 16385,
  'gemini-pro': 128000,
  'llama-3-70b': 8192,
  'default': 128000,
};

// 阈值配置
const WARNING_THRESHOLD = 70;      // 警告阈值（%）
const CRITICAL_THRESHOLD = 90;     // 严重警告阈值（%）

/**
 * 估算文本的 token 数量
 * 中文约 1.5 字符/token，英文约 4 字符/token
 */
function estimateTokens(text: string): number {
  if (!text) return 0;
  const chineseChars = (text.match(/[\u4e00-\u9fa5]/g) || []).length;
  const englishChars = text.length - chineseChars;
  return Math.round(chineseChars / 1.5 + englishChars / 4);
}

/**
 * 生成进度条
 * @param percentage 百分比 (0-100)
 * @param length 进度条长度 (默认 20)
 */
function generateProgressBar(percentage: number, length: number = 20): string {
  const filled = Math.round((percentage / 100) * length);
  return '▓'.repeat(filled) + '░'.repeat(length - filled);
}

/**
 * 格式化数字（添加千位分隔符）
 */
function formatNumber(num: number): string {
  return num.toLocaleString();
}

/**
 * 获取模型的上下文窗口限制
 */
function getModelContextLimit(modelName: string): number {
  if (!modelName) return MODEL_LIMITS.default;
  if (MODEL_LIMITS[modelName]) return MODEL_LIMITS[modelName];
  
  // 模糊匹配
  for (const [key, limit] of Object.entries(MODEL_LIMITS)) {
    if (modelName.toLowerCase().includes(key)) return limit;
  }
  return MODEL_LIMITS.default;
}

/**
 * 计算会话的 token 使用统计
 */
function calculateTokenStats(sessionHistory: any[], modelName: string) {
  const limit = getModelContextLimit(modelName);
  let usedTokens = 0;
  
  for (const message of sessionHistory) {
    if (message.content) {
      usedTokens += estimateTokens(message.content);
    }
    if (message.tool_calls) {
      for (const tool of message.tool_calls) {
        usedTokens += estimateTokens(JSON.stringify(tool));
      }
    }
  }
  
  const percentage = Math.min((usedTokens / limit) * 100, 100);
  const remaining = limit - usedTokens;
  
  return {
    used: usedTokens,
    limit,
    percentage,
    remaining,
  };
}

/**
 * 生成上下文状态消息
 */
function generateStatusMessage(stats: any, modelName: string): string {
  const { percentage, used, limit, remaining } = stats;
  
  let icon = '📊';
  let statusText = '正常';
  let advice = '> ✅ 上下文使用正常，可以继续对话';
  
  if (percentage >= CRITICAL_THRESHOLD) {
    icon = '🚨';
    statusText = '严重';
    advice = '> 🚨 **严重警告：** 上下文即将超限！建议立即使用 `/new` 开启新会话';
  } else if (percentage >= WARNING_THRESHOLD) {
    icon = '⚠️';
    statusText = '警告';
    advice = '> 💡 **建议：** 使用 `/new` 开启新会话 或 `/compact` 压缩上下文';
  } else if (percentage >= 50) {
    advice = '> ✅ 上下文使用正常，可以继续对话';
  }
  
  const progressBar = generateProgressBar(percentage);
  
  let message = `### ${icon} 上下文使用状态\n\n`;
  message += `**状态：** ${statusText}\n`;
  message += `**模型：** ${modelName}\n\n`;
  message += `**使用率：** ${percentage.toFixed(1)}%\n`;
  message += `\`${progressBar}\`\n\n`;
  message += `**已使用：** ${formatNumber(used)} tokens\n`;
  message += `**剩余：** ${formatNumber(remaining)} tokens\n`;
  message += `**总计：** ${formatNumber(limit)} tokens\n\n`;
  message += advice;
  
  return message;
}

/**
 * Skill 主函数
 */
export default async function contextUsageChecker(params: any) {
  const { runtime, reply } = params;
  
  try {
    // 获取当前会话历史
    const sessionHistory = runtime?.session?.history || [];
    const modelName = runtime?.agent?.model?.id || 'qwen3.5-plus';
    
    // 计算 token 使用统计
    const stats = calculateTokenStats(sessionHistory, modelName);
    
    // 生成状态消息
    const statusMessage = generateStatusMessage(stats, modelName);
    
    // 回复用户
    await reply({ text: statusMessage });
    
  } catch (error) {
    // 错误处理
    const errorMessage = `### ❌ 查询失败\n\n无法获取上下文使用率：${error instanceof Error ? error.message : String(error)}\n\n请重试或联系管理员。`;
    await reply({ text: errorMessage });
  }
}

// 导出工具函数供其他模块使用
export {
  estimateTokens,
  generateProgressBar,
  formatNumber,
  getModelContextLimit,
  calculateTokenStats,
  generateStatusMessage,
  MODEL_LIMITS,
  WARNING_THRESHOLD,
  CRITICAL_THRESHOLD,
};


path: tsconfig.json
content: {
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "strict": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "lib": ["ES2022"]
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist", "tests"]
}


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)