Skip to content

CLI 1.1.64:排队条与账号额度(115)的三处静默——字段没被解析、显示没开关、变量没文档 #7

Description

@Capricornus007

环境

  • Qoder CLI 1.1.64(qodercli --version),Linux x86_64,Artix
  • 账号:付费方案,qfmodel + contextWindow=1000000 + reasoning.effort=xhigh
  • 已通过 /feedback 提交过一份同样内容的反馈,这里是可公开追踪的版本
  • 下面每一条都附了任何人都能重跑的取证命令,命令里的路径用 $(readlink -f "$(command -v qodercli)") 取当前二进制,不依赖我的机器

1) code 115 / agentLimitResetTime 被客户端完全忽略,长对话因此静默失去自动压缩

2026-09-26 本机 /tmp 在 12 小时 45 分钟内累积 148 个 API 错误转储(文件名形如
qoder-cli-error-generateContent-api-*.json),全部是同一个错误:

Qoder API error: FORBIDDEN - {"code":"115","message":"{\"agentLimitResetTime\":1792299071823}"}

agentLimitResetTime 换算成本地时间是 2026-10-18 13:51(一个计费周期等级的重置点,不是短冷却)。
被拒的不是我的交互请求——同一时段交互回合、git push、GitHub API 查询都正常通过——而是每个回合附带发出的
后台请求
:每个转储的 context[0].content 都是本会话的对话转储(User: … ⏎ Assistant: … ⏎ Tool Bash: …,
中段截断)并以该 session 最新一条回复结尾,形状就是上下文压缩/摘要那条路径。

问题在于这一切对 UI 完全不可见:二进制里根本没有这个字段名,所以它不可能被显示。

B=$(readlink -f "$(command -v qodercli)")
grep -a -c 'agentLimitResetTime' "$B"   # → 0
grep -a -c 'code===115' "$B"            # → 0

后果:1M 上下文的长 session 会在用户不知情的情况下失去自动压缩,越用越接近硬失败,而屏幕上没有任何一行字
说明这件事。请把后台配额耗尽变成可见状态(例如一行
后台压缩不可用,至 2026-10-18 恢复),或者不要让压缩走一条会被账号额度杀死的通路。

2) Model request queued … / ▊ moving / estimated wait 5min 没有任何开关可以关

这三行 + 那根条,是排队时唯一的信息。我查过设置项,客户端共有 68 个 ui.* 键,没有一个和排队相关:

python3 - <<'PY'
import os,re
B=os.path.realpath(os.popen('command -v qodercli').read().strip())   # 当前 CLI 二进制
d=open(B,'rb').read()
keys=sorted(set(re.findall(rb'\bui\.[A-Za-z][A-Za-z0-9]{2,24}',d)))
print(len(keys))
print([k.decode() for k in keys if any(w in k.lower() for w in (b'queue',b'spin',b'wait'))])
# → 68
# → []
PY

ui.showSpinner:false 只去掉 ✦,文字和条照样画。而那根条的宽度纯粹由「已经等了多久」推出来:
旁边的文案常量只有三档(estimated wait less than 1min / estimated wait 1min / estimated wait over 10min),
所以它「一直在动、却永远没有进度」是设计行为——看起来像挂死。

3) 服务端其实回了真实等待信息,UI 却没有用它

同一个二进制里有这些标识符(grep -a -o 都能命中):
isQueued、queueType、waitTime、retryAfterSeconds、serviceAvailable、
以及遥测字段 queueServerWaitTimeMs / queueServerRetryAfterMs / queuePollCount / queueRecoveryAttempt。
也就是说真实等待值是拿得到的,但显示层只剩一个 elapsed 动画。请二选一:把条改成按服务端 waitTime/retryAfterSeconds
推进,或者加一个开关让我能把它收起来(ui.modelQueue: off | text | bar)。

4) QODER_MODEL_QUEUE_MAX_WAIT_MS 没有文档,而且它的语义容易反

代码里的实际逻辑是:默认 3600000(1 小时),并且扣掉累计已经等过的时间,减到 0 才放弃——

i = t.queueTelemetry.waitMs ?? 0, s = Twe() /* 上限 */, a = s - i;
if (a <= 0) throw up("model queue wait timeout", …)

(Twe() 读 process.env.QODER_MODEL_QUEUE_MAX_WAIT_MS,未设则用 3600000。)
这意味着它是放弃点不是加速键,等待时间还跨重试累计:我把它设成 30000(30 秒)之后,尖峰时段是更快报错,
但不会更快拿到结果。这个变量和 115 / agentLimitResetTime 一样在官方文档里查不到,请补进文档,
并说明「排队时客户端到底知不知道还要等多久」。


我要的三件事,按优先级

  1. 后台配额(115)耗尽要在 UI 可见,且带重置时间。
  2. 排队显示给一个开关(off | text | bar),或者让条按服务端真实 waitTime 走。
  3. QODER_MODEL_QUEUE_MAX_WAIT_MS、code 115、agentLimitResetTime 写进文档。

一点补充(不影响上面三条)

那些 API 错误转储写进 /tmp 时的权限是 -rw-r--r--(0644),内容是整个会话的对话转储。
在共享机器 / 容器里这本身就是一个泄漏面,建议直接写成 0600。
我本机已经手动 chmod 600 过,所以这条只是提醒默认值。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions