paper-burner/js/process/utils.js

75 lines
3.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 计算指数退避的重试延迟,并加入抖动以减少多个实例同时重试的概率。
*
* 主要逻辑:
* 1. 根据重试次数计算基础的指数延迟 (baseDelay * 2^retryCount)。
* 2. 生成一个抖动值,其范围是指数延迟的 ±10% (即 exponentialDelay * 0.2 * (Math.random() - 0.5))。
* 3. 将抖动值加到指数延迟上。
* 4. 确保总延迟不超过 `maxDelay`。
* 5. 确保总延迟不小于 `baseDelay` (以防抖动导致延迟过小)。
*
* @param {number} retryCount - 当前重试次数 (从0开始计数)。
* @param {number} baseDelay - 基础延迟时间 (毫秒),默认为 500ms。
* @param {number} maxDelay - 最大延迟时间 (毫秒),默认为 30000ms。
* @returns {number} 计算后并应用了抖动和上下限的延迟时间 (毫秒)。
*/
function getRetryDelay(retryCount, baseDelay = 500, maxDelay = 30000) {
const exponentialDelay = baseDelay * Math.pow(2, retryCount);
// 抖动: 在 ±10% 范围内随机浮动
const jitter = exponentialDelay * 0.2 * (Math.random() - 0.5);
const totalDelay = Math.min(exponentialDelay + jitter, maxDelay);
return Math.max(totalDelay, baseDelay);
}
/**
* 基于文本特性估算其 token 数量。
* 此方法为启发式估算,并非精确计数,主要针对不同语言特性采用不同策略。
*
* 主要逻辑:
* 1. 如果文本为空或未定义,直接返回 0。
* 2. 计算文本中非 ASCII 字符 (粗略地判断为 CJK 字符等) 的比例。
* 3. **CJK 语言处理**: 如果非 ASCII 字符的比例超过一个阈值 (例如 0.3),则认为文本主要由 CJK 字符构成。
* 此时token 数大致估算为 `text.length * 1.1` (一个字符约等于 1.1 个 token)。
* 4. **其他语言处理 (如英文、代码)**: 否则,认为文本主要由 ASCII 字符构成。
* 此时token 数大致估算为 `text.length / 3.5` (约 3-4 个字符为一个 token)。
* 5. 对估算结果向上取整。
*
* @param {string} text - 需要估算 token 数的输入文本。
* @returns {number} 估算出的 token 数量。
*/
function estimateTokenCount(text) {
if (!text) return 0;
// 针对CJK等非ASCII字符的优化估算
const nonAsciiRatio = (text.match(/[^ - ]/g) || []).length / text.length;
if (nonAsciiRatio > 0.3) { // 中日韩等语言的启发式判断
return Math.ceil(text.length * 1.1);
} else {
// 英文和代码大约3-4个字符一个token
return Math.ceil(text.length / 3.5);
}
}
/**
* 转义字符串中的正则表达式特殊字符。
* 当需要将一个普通字符串用作正则表达式的一部分进行精确匹配时,
* 该字符串中可能包含的正则表达式特殊字符 (如 `.`、`*`、`+`、`?` 等) 需要被转义,
* 以确保它们被解释为字面量字符而不是元字符。
*
* 主要逻辑:
* - 使用 `String.prototype.replace()` 方法。
* - 正则表达式 `/[.*+?^${}()|[\\]\\]/g` 匹配所有常见的正则表达式特殊字符。
* - 替换函数 `$&` 表示匹配到的整个子字符串,在其前面加上反斜杠 `\\` 进行转义。
*
* @param {string} string - 需要转义的原始字符串。
* @returns {string} 特殊字符已被转义的字符串,可以直接安全地用于构建新的正则表达式。
*/
function escapeRegex(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
// 将工具函数添加到processModule对象
if (typeof processModule !== 'undefined') {
processModule.getRetryDelay = getRetryDelay;
processModule.estimateTokenCount = estimateTokenCount;
processModule.escapeRegex = escapeRegex;
}