refactor: dedupe shared implementations — shared fetchRetry with restored network-error retry, single normalizeName, unified token estimate (Fixes #2) - #3
Merged
Conversation
A1. Consolidate duplicated fetchRetry into src/engine/http.ts
- llm.ts / embed.ts each carried a near-identical copy that had
already drifted: the llm side lost the network-error retry branch
during an earlier refactor. Shared module restores it for both.
- Timeout errors are now a typed HttpTimeoutError; per-caller
semantics preserved via retryOnTimeout (llm: false — a 60s
timeout must not quadruple worst-case latency; embed: true).
- Exhausted status retries now return the last response instead of
a generic "failed after retries" error, so callers surface
status-specific messages.
- Add unit tests (8) covering status retry, network-error retry,
timeout semantics, and label formatting.
A2. extract.ts imports normalizeName from store.ts instead of carrying
a byte-identical copy guarded by a cross-file consistency test.
A3. New src/tokens.ts (CHARS_PER_TOKEN + estimateTokens); index.ts,
recall.ts and assemble.ts now share the /3 heuristic.
A4. Drop RecallResult.tokenEstimate — computed in three places, never
read by anyone (updated 4 test fixtures accordingly).
B1. store.ts uid(): crypto.randomUUID() replaces the hand-rolled
Date.now()+Math.random() suffix.
B3(partial). index.ts: extractAssistantText/extractUserText share
textFromBlocks(); llm.ts/store.ts block-parsing left as-is
(different input shapes).
Deliberately out of scope: oauth.ts toBase64Url wrapper (cosmetic),
JWT/SSE hand-rolled parsers (zero-dependency by design).
tsc clean; vitest 241 passed / 76 skipped. The one failure
(installer-upgrade, spawnSync bash ETIMEDOUT) is a pre-existing sandbox
networking limitation, reproduced on the unmodified branch.
Fixes #2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2(重复造轮子排查的落地实施)。计划与内部评估结论见下。
A1. 合并
fetchRetry→ 新建src/engine/http.ts(含行为修复)两份近重复实现已漂移:llm.ts 在早前重构中丢失了网络异常重试分支。合并后:
HttpTimeoutError区分,新增retryOnTimeout选项保留双方原有语义:llm=false(60s 超时不能把最坏阻塞时间翻 4 倍)、embed=true!res.ok分支能给出带状态码的具体报错(行为改进)label参数保持逐字兼容([graph-memory] LLM request timed out after Xms等),不影响llm-guard的状态码解析test/http-retry.test.ts8 个单测(backoffMs 可注入),覆盖 429 重试 / 网络错误重试(回归保护) / 超时两种语义 / 401 不重试 / label 格式A2.
normalizeName单源化extract.ts 删除逐字节相同的副本改从 store.ts import;删除 normalize-name.test.ts 中"跨文件一致性"描述块(该测试是在给重复上保险),行为断言全保留。
A3. token 估算单源化
新建
src/tokens.ts(CHARS_PER_TOKEN+estimateTokens(chars)),index.ts / recall.ts / assemble.ts 三处统一接入,字符累加逻辑保持不变(舍入逐位一致)。A4. 删除
RecallResult.tokenEstimate三处计算、零消费方。types.ts、recall.ts 与 4 处测试夹具同步清理。
B1 / B3
uid()改用crypto.randomUUID()(消除同毫秒碰撞可能)extractAssistantText/extractUserText共享textFromBlocks();llm.ts / store.ts 的 block 解析输入结构不同,刻意不合并明确不做(与 issue 一致)
toBase64Url一行包装(纯审美 churn)验证
tsc --noEmit:干净vitest run:241 passed / 76 skipped(基线 239 + 新增 8 个 http 单测 − 移除 6 个一致性测试)installer-upgrade(spawnSync bash ETIMEDOUT)为沙箱网络限制,未改动分支上同样失败16 files changed, +268 / −129(含两个新模块与一个新测试文件)