mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-04 19:28:46 +01:00
Accept independent Grok reasoning counters in prompt receipts
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
b5b0dbb03f
commit
ad07e681ba
3 files changed
+25
-3
No files matched your search
@@ -21,12 +21,29 @@ describe("Grok terminal prompt usage", () => {
|
|||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
{ usageIsIncomplete: true }, { usageIsIncomplete: "false" }, { cachedReadTokens: 505796 },
|
{ usageIsIncomplete: true }, { usageIsIncomplete: "false" }, { cachedReadTokens: 505796 },
|
||||||
{ inputTokens: -1 }, { outputTokens: 1.5 }, { reasoningTokens: 5764 }, { totalTokens: 1 },
|
{ inputTokens: -1 }, { outputTokens: 1.5 }, { reasoningTokens: -1 }, { reasoningTokens: 1.5 }, { totalTokens: 1 },
|
||||||
{ modelCalls: undefined }, { inputTokens: Number.MAX_SAFE_INTEGER + 1 },
|
{ modelCalls: undefined }, { inputTokens: Number.MAX_SAFE_INTEGER + 1 },
|
||||||
])("refuses incomplete or invalid token authority: %j", patch => {
|
])("refuses incomplete or invalid token authority: %j", patch => {
|
||||||
expect(grokPromptUsage({ ...meta, usage: { ...usage, ...patch } }, "session-1")).toBeNull();
|
expect(grokPromptUsage({ ...meta, usage: { ...usage, ...patch } }, "session-1")).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("settles a real Grok prompt whose reasoning counter exceeds its output counter", () => {
|
||||||
|
const collector = createGrokPromptUsageCollector();
|
||||||
|
collector.begin("runner-1", "session-1");
|
||||||
|
collector.observe("outbound", request);
|
||||||
|
collector.observe("inbound", { ...response, result: { _meta: { ...meta, usage: {
|
||||||
|
inputTokens: 517350, outputTokens: 7969, totalTokens: 525319, cachedReadTokens: 458624,
|
||||||
|
cacheCreationTokens: 0, reasoningTokens: 9859, modelCalls: 15, costUsdTicks: 4537320000,
|
||||||
|
} } } });
|
||||||
|
const state = { lastRequestId: "runner-1", terminalPromptUsage: collector.snapshot() };
|
||||||
|
expect(persistedAcpxTurnUsage({}, state, "runner-1")).toEqual({
|
||||||
|
type: "status", tag: "usage_update", text: "terminal prompt usage",
|
||||||
|
cost: { amount: 0.453732, currency: "USD", basis: "turn" },
|
||||||
|
breakdown: { inputTokens: 58726, outputTokens: 7969, totalTokens: 525319,
|
||||||
|
cachedReadTokens: 458624, cachedWriteTokens: 0, thoughtTokens: 0 },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it.each([{ costUsdTicks: undefined }, { costUsdTicks: -1 }, { costIsPartial: true }, { costIsPartial: "false" }])(
|
it.each([{ costUsdTicks: undefined }, { costUsdTicks: -1 }, { costIsPartial: true }, { costIsPartial: "false" }])(
|
||||||
"preserves complete tokens without inventing cost: %j", patch => {
|
"preserves complete tokens without inventing cost: %j", patch => {
|
||||||
const result = grokPromptUsage({ ...meta, usage: { ...usage, ...patch } }, "session-1");
|
const result = grokPromptUsage({ ...meta, usage: { ...usage, ...patch } }, "session-1");
|
||||||
|
|||||||
@@ -16,8 +16,7 @@ export function grokPromptUsage(metaValue: unknown, sessionId: string): Omit<Ter
|
|||||||
const { inputTokens, outputTokens, totalTokens, cachedReadTokens, cacheCreationTokens, reasoningTokens, modelCalls } = usage;
|
const { inputTokens, outputTokens, totalTokens, cachedReadTokens, cacheCreationTokens, reasoningTokens, modelCalls } = usage;
|
||||||
if (![inputTokens, outputTokens, totalTokens, cachedReadTokens, cacheCreationTokens, reasoningTokens, modelCalls].every(integer)
|
if (![inputTokens, outputTokens, totalTokens, cachedReadTokens, cacheCreationTokens, reasoningTokens, modelCalls].every(integer)
|
||||||
|| Number(inputTokens) + Number(outputTokens) !== totalTokens
|
|| Number(inputTokens) + Number(outputTokens) !== totalTokens
|
||||||
|| Number(cachedReadTokens) + Number(cacheCreationTokens) > Number(inputTokens)
|
|| Number(cachedReadTokens) + Number(cacheCreationTokens) > Number(inputTokens)) return null;
|
||||||
|| Number(reasoningTokens) > Number(outputTokens)) return null;
|
|
||||||
const costKnown = integer(usage.costUsdTicks) && (usage.costIsPartial === undefined || usage.costIsPartial === false);
|
const costKnown = integer(usage.costUsdTicks) && (usage.costIsPartial === undefined || usage.costIsPartial === false);
|
||||||
return {
|
return {
|
||||||
promptId: meta.promptId,
|
promptId: meta.promptId,
|
||||||
|
|||||||
@@ -2188,6 +2188,12 @@ an API-key pass must not be reported as subscription evidence. See
|
|||||||
[`doc/grok-native-runner.md`](../../doc/grok-native-runner.md) for installation,
|
[`doc/grok-native-runner.md`](../../doc/grok-native-runner.md) for installation,
|
||||||
credential boundaries and repetition requirements.
|
credential boundaries and repetition requirements.
|
||||||
|
|
||||||
|
Grok accounting uses the complete prompt ledger bound to the matching ACP
|
||||||
|
response. Its reasoning counter can exceed its output counter; it is not a
|
||||||
|
validation bound or an extra term in the ledger's input-plus-output total.
|
||||||
|
Reported cost remains authoritative. See the upstream
|
||||||
|
[`UsageTotals` ledger](https://github.com/xai-org/grok-build/blob/2bdd1d6a6369de0e8c68132ea4539e9abd9e14a8/crates/codegen/xai-chat-state/src/usage.rs).
|
||||||
|
|
||||||
### Kimi Code qualification
|
### Kimi Code qualification
|
||||||
|
|
||||||
`kimi-qualification` is a separate explicit-only candidate suite for maintained
|
`kimi-qualification` is a separate explicit-only candidate suite for maintained
|
||||||
|
|||||||
Reference in new issue
Block a user