Commit Graph

234 Commits

Author SHA1 Message Date
iomgaa 82f4ec4910 feat: model the thinking switch as shape plus capability (issue #5)
enable_thinking=False was a no-op for minimax and openai sources: both
profiles had empty dicts on each side, so the payload update injected
nothing while the caller believed reasoning had been turned off. A
downstream project was blocked on exactly this.

The root cause is that an empty dict meant two different things -- "no
injection needed" and "we do not know how this provider spells it" --
and that a provider-level table cannot express what turned out to be a
per-model property. Live testing showed MiniMax-M3 can disable
reasoning via reasoning_effort while M2.7 and M2.5 cannot be disabled
at all, which two external registries independently confirm.

So the shape stays at provider level and a capability table joins it at
model level. Unknown, unsupported and no-opinion are now three distinct
values, and resolve_thinking is the single place they meet: it raises at
assembly time when a model cannot honour the request, warns and injects
for unregistered models, and injects silently otherwise. Every registered
capability carries the evidence it was derived from.

enable_thinking also joins the cache fingerprint, since it now really
does change the request body.
2026-08-02 06:20:24 -04:00
iomgaa 89ff916bc8 feat: collect reasoning_tokens from the provider usage payload (issue #6)
Reasoning tokens are already counted inside completion_tokens, so the
cost total was never wrong -- what was missing is the attribution: how
much of a call was spent thinking rather than answering.

LLMResponse and TransportResult each gain a trailing reasoning_tokens
field, and the telemetry port grows from 21 to 22 columns with the new
column appended in both backends so fresh and migrated schemas keep the
same physical order.

None means this particular call did not report the field, not that the
source never reports it: a relay that falls back to a local tokenizer
replaces the whole usage object and drops completion_tokens_details.
Downstream checks must therefore read "in (None, 0)"; no provider was
observed reporting a literal zero.
2026-08-02 05:55:37 -04:00
iomgaa e5871cccd2 docs: add implementation plan for thinking capability and reasoning tokens
Ten tasks in a fixed order: land reasoning_tokens first so it can serve
as the acceptance instrument for the thinking-switch fix, then reshape
the provider profile, add the model-level capability table, wire the
assembly guard, fold enable_thinking into the cache fingerprint, and
verify the whole thing against the live API.

Incorporates a read-only Codex review: resolve_thinking now takes the
model name so its errors can name it, and the warning assertion uses a
loguru sink because caplog cannot see loguru output.
2026-08-02 05:49:55 -04:00
iomgaa 781579bf36 docs: record thinking-switch findings and capability design (issue #5, #6)
Findings: live-API measurements across MiniMax M3/M2.7/M2.5, qwen and
deepseek, plus a survey of how nine unified gateways model per-model
parameter divergence. Key facts: reasoning_effort is MiniMax's real
switch, M2.x reasoning is mandatory and cannot be disabled, and the
relay's local token-count fallback silently drops reasoning_tokens.

Design: keep the parameter shape at provider level, push capability
down to model level, split "unknown" / "unsupported" / "no opinion"
into three distinct values, and fail at assembly time when a model
cannot honour enable_thinking=False.
2026-08-02 05:42:05 -04:00
iomgaa acc419a29b chore: add a mechanical wiki-vs-source alignment checker
七轮人工审查的 88 条发现里,签名/导出/字段序/列数/env 键这几类是机械可
比对的,不该靠人一轮轮追。五项检查全部由源码反推,已用注入历史错误的方式
验证有效: gather_bounded(coros, limit)、source_name 排进前 11 位、列数写
成 20、EXTRA_BODY 漏文档 —— 四条全部命中。

不并入 make ci: wiki 是独立仓库,仓库里没有它时自动跳过等于静默降级(违
P5),故做成显式的 make wiki-check WIKI=<path>。
2026-08-02 02:16:16 -04:00
iomgaa de7273598e docs: correct the scope normalization comment on Redis key impact
Both Redis backends have lowercased scope in their own constructors since
v1.0.0, so case never split the keyspace. What actually does is whitespace:
the backends lower but do not strip.
2026-08-02 00:38:42 -04:00
iomgaa ce630a37ef feat: pass sampling parameters through to the provider (issue #4) v1.0.5 2026-08-01 00:00:44 -04:00
iomgaa dfda59fec2 chore: release 1.0.5 with sampling parameter passthrough 2026-07-31 23:52:49 -04:00
iomgaa 15b9b02e96 fix: make the sampling invariant test actually enforce the constraint
The test passed overlay and sampling as separate objects while production
aliases them, so an in-place mutation slipped through it. Also syncs the
telemetry schema page and adds the missing postgres round-trip assertion.
2026-07-31 22:01:51 -04:00
iomgaa cce7562d07 test: verify sampling parameters through the full governance stack 2026-07-31 21:46:05 -04:00
iomgaa 2958dc8231 docs: document sampling passthrough and the empty thinking profiles 2026-07-31 21:41:34 -04:00
iomgaa a5ebf72f17 feat: strip extra_body on the embedding and OCR paths with a warning
Stripping is load-bearing, not tidying: those transports never send the
value, so leaving it would make telemetry record a parameter never sent.
2026-07-31 21:36:50 -04:00
iomgaa 4516761dbe feat: record sampling parameters in telemetry (port 20 to 21 fields)
Each of the three emitter entry points has a pinned meaning: only the
attempt path has an effective source, so only it merges extra_body.
2026-07-31 21:30:45 -04:00
iomgaa b6e4cc3f3b test: lock the sampling snapshot invariant across the onion
Verified by breaking structured.py so the reask drops sampling: the test
goes red for the right reason, not merely because something errored.
2026-07-31 21:23:50 -04:00
iomgaa c31cc1adad feat: fold sampling parameters into the cache key
Without this, five seeds over identical messages all hit the first cached
response and the reported standard deviation is silently always zero.
2026-07-31 21:20:56 -04:00
iomgaa 6bb64ca938 feat: accept sampling overlay on chat() and per-source extra_body
Priority is structured injection > per-call overlay > per-source config,
and extra_body now takes part in the cache fingerprint.
2026-07-31 21:17:49 -04:00
iomgaa 152fa264ed feat: parse EXTRA_BODY as a JSON object per source 2026-07-31 21:12:06 -04:00
iomgaa 6023d11bfb feat: add sampling overlay validation and source extra_body
Three pure helpers in the innermost layer plus ChatRequest.sampling as a
cross-layer snapshot, so cache keys and telemetry read one stable value.
2026-07-31 21:09:03 -04:00
iomgaa b12bf6ce79 docs: plan the sampling parameter implementation (issue #4)
Eleven verifiable tasks covering decisions A-G and the 14 test items,
with the reviewer-found execution traps written into the tasks.
2026-07-31 13:01:53 -04:00
iomgaa b24e224beb docs: soften the non-chat extra_body gate to strip-and-warn
Stripping is load-bearing: without it telemetry would record a sampling
parameter that was never sent on the OCR and embedding paths.
2026-07-31 12:31:31 -04:00
iomgaa 09e77f11f8 docs: register the sampling design in the research wiki 2026-07-31 12:00:20 -04:00
iomgaa 0cc89fb03c docs: harden the sampling design against the reviewer findings
Pin the telemetry column semantics across all three emitter entry points,
add the cross-layer sampling snapshot, and reject extra_body on the
embedding and OCR paths instead of accepting it silently.
2026-07-31 11:57:39 -04:00
iomgaa 20fd899d93 docs: design sampling parameter passthrough (issue #4)
Two-layer entry: per-call overlay on chat() and per-source extra_body.
Covers the cache-key and telemetry interactions the issue omitted.
2026-07-31 11:40:14 -04:00
iomgaa 486809b08b feat: expose provider cache tokens and reported model (issue #3) v1.0.4 2026-07-31 11:15:18 -04:00
iomgaa 58cb55b869 chore: release 1.0.4 instead of a minor bump 2026-07-31 11:11:55 -04:00
iomgaa 86fb4d5536 fix: keep the postgres backfill from disabling telemetry or locking the table 2026-07-31 10:42:55 -04:00
iomgaa 32d7869043 fix: harden the observability fields against the verifier findings 2026-07-31 08:28:41 -04:00
iomgaa 966d548245 chore: release 1.1.0 with the response observability fields 2026-07-31 08:08:37 -04:00
iomgaa c2fcd5b1f8 feat: record the observability fields end to end through telemetry 2026-07-31 08:03:43 -04:00
iomgaa 0ed9dc107c feat: support a cached input price tier in the pricing table 2026-07-31 07:58:37 -04:00
iomgaa c4eda119ac feat: carry the new observability fields through retry and cache 2026-07-31 07:56:04 -04:00
iomgaa cd1a9520ff docs: spell out that a reported zero is not a missing value 2026-07-31 07:53:42 -04:00
iomgaa 0aa7202c87 feat: collect provider cache tokens and reported model in transport 2026-07-31 07:51:47 -04:00
iomgaa 4841d901af feat: add cached prompt tokens and reported model to response types 2026-07-31 07:48:35 -04:00
iomgaa 30d7ffd94a docs: register the implementation plan in the research wiki 2026-07-31 07:11:52 -04:00
iomgaa 037e7a011e docs: fold the plan review findings into the plan 2026-07-31 07:09:52 -04:00
iomgaa 0e2f734b0b docs: plan the implementation of the observability fields 2026-07-31 06:59:42 -04:00
iomgaa 7ccb25e8f1 docs: record the human approval of the design decisions 2026-07-31 06:54:55 -04:00
iomgaa 42d16919fc docs: register the design in the research wiki 2026-07-31 04:37:52 -04:00
iomgaa 005a90ca19 docs: fold the independent review findings into the design 2026-07-31 04:35:51 -04:00
iomgaa 8a824e2000 docs: design the response observability fields for issue 3 2026-07-31 04:22:51 -04:00
iomgaa 8495cea5dc docs: close out the plan with the external deliverables done
Wiki site synced across six pages (commit 4c8dc09 on the wiki repo) and
issue #2 answered with the shipping conditions for the downstream
workaround removal.
v1.0.3
2026-07-30 12:17:58 -04:00
iomgaa abca723d3d chore: release 1.0.3 with the est_tokens decoupling
Patch level: no field or env key was removed or renamed, no port
signature moved, and the API stays backward compatible -- what changed
is the telemetry data contract, which the changelog spells out for
downstream cost rollups.
2026-07-30 12:14:35 -04:00
iomgaa 63b85508c7 docs: tick off the plan items that are actually done
Leaves the wiki-site sync, the issue #2 reply and the version bump
unticked -- those are external deliverables this repository cannot
self-certify, and the pre-merge review was right to flag their absence.
2026-07-30 11:29:56 -04:00
iomgaa 4e06d5e801 docs: widen the GovDoc usage_source note to three states
The migration doc is a standing constraint on library design, so an
outdated enum there states an outdated fact. B13's substance survives
the change -- GovDoc's zero was never the problem, the missing label
was -- but the row now names unavailable and the cache_hit-qualified
gap query alongside it.
2026-07-30 11:18:44 -04:00
iomgaa 4e5a91d802 docs: log the est_tokens decoupling behavior changes 2026-07-30 11:12:43 -04:00
iomgaa 9e2d8ee43c docs: mark EST_TOKENS optional in the env template 2026-07-30 11:12:43 -04:00
iomgaa d1520cc0a5 docs: realign authoritative docs with the three-state usage_source
ARCHITECTURE.md 四处: §4.4 预扣量改指 effective_est_tokens(); §5.1 补三态值域表与
cost NULL 口径(含缓存命中行的例外与缺口查询必带 cache_hit 限定); §7.1 打捞路径
由强制 estimated 改为仅在收到 usage 帧时降级; §7.7 est_tokens 降为可选调优覆盖并
写明 tpm//60 派生规则与既有的全局 TPM 闸限制。

migrations/chsanalyzer.md 行 151 由保留改判有意放弃并写入理由; G2 标记已闭。
schemas/llm-calls.md 同步三态与 cost 口径。
2026-07-30 11:11:01 -04:00
iomgaa ab496bb298 feat: let tpm be configured without an est_tokens companion
The gate check forced operators to guess a per-call token size before
they could enable the TPM gate at all; est_tokens is now an optional
tuning override and effective_est_tokens() derives the reservation from
the provider quota. Reservation and settlement already read the same
derived value, so the deposit still nets to zero on both the success
path and the non-dead transient failure path.

The rest of _validate_gates is untouched, and the est_tokens field plus
its EST_TOKENS env key stay put for migration compatibility.
2026-07-30 10:57:40 -04:00
iomgaa cd8bebba00 refactor: drop the now-unused source parameter from usage resolvers
三态兜底不再读源配置,_resolve_usage / _resolve_stream_usage /
_resolve_embedding_usage 的 source 形参已成死参数;保留它等于在签名上继续
宣称用量口径依赖源配置,与本次改动切断该依赖的意图相悖。同步三个调用点
与测试的直接调用;SourceConfig 仍被文件内错误翻译等函数使用,import 保留。
2026-07-30 10:46:52 -04:00