mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-28 20:21:50 +01:00
Label Pi pricing estimates and ignore duplicate stale failure receipts
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
14e1e09a79
commit
ba7841ca3b
3 files changed
+15
-7
No files matched your search
@@ -73,7 +73,9 @@ describe("Pi ACP bridge", () => {
|
||||
expect(usage.response()).toMatchObject({ usage: { totalTokens: 10 }, _meta: { jetbrains: { air: { sessionFailure: { severity: "error" } } } } });
|
||||
usage.accept({ ...failed, timestamp: 2, stopReason: "stop" });
|
||||
expect(usage.response()).toMatchObject({ usage: { inputTokens: 8, totalTokens: 20 } });
|
||||
usage.accept(failed); // A duplicate old failure cannot undo a successful retry.
|
||||
expect(usage.response()._meta).toBeUndefined();
|
||||
expect(usage.response()).toMatchObject({ usage: { _meta: { paperclipPi: { costUsd: 0.02, costSource: "pi_pricing_estimate" } } } });
|
||||
usage.reset(); expect(usage.response()).toEqual({});
|
||||
});
|
||||
|
||||
|
||||
@@ -222,12 +222,15 @@ export class PiTurnUsage {
|
||||
accept(value: unknown): void {
|
||||
const message = record(value);
|
||||
if (message.role !== "assistant") return;
|
||||
this.failed = message.stopReason === "error";
|
||||
if (!message.usage || typeof message.usage !== "object") return;
|
||||
if (!message.usage || typeof message.usage !== "object") {
|
||||
this.failed = message.stopReason === "error";
|
||||
return;
|
||||
}
|
||||
const key = JSON.stringify([message.timestamp, message.id, message.usage, message.content]);
|
||||
if (this.seen.has(key)) return;
|
||||
if (this.seen.size >= 8192) throw new Error("Pi usage receipts exceed their bound");
|
||||
this.seen.add(key);
|
||||
this.failed = message.stopReason === "error";
|
||||
const usage = record(message.usage);
|
||||
const valid = (value: unknown): value is number => typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
||||
const fields = ["inputTokens", "outputTokens", "cachedReadTokens", "cachedWriteTokens"] as const;
|
||||
@@ -249,7 +252,7 @@ export class PiTurnUsage {
|
||||
|
||||
response(): RecordValue {
|
||||
return {
|
||||
...(this.observed ? { usage: { ...Object.fromEntries(Object.entries(this.total).filter(([name]) => !this.unknown.has(name as keyof typeof this.total))), _meta: { paperclipPi: { provenance: "assistant_message_receipts", ...(this.costObserved && !this.costIncomplete ? { costUsd: this.cost } : {}) } } } } : {}),
|
||||
...(this.observed ? { usage: { ...Object.fromEntries(Object.entries(this.total).filter(([name]) => !this.unknown.has(name as keyof typeof this.total))), _meta: { paperclipPi: { provenance: "assistant_message_receipts", ...(this.costObserved && !this.costIncomplete ? { costUsd: this.cost, costSource: "pi_pricing_estimate" } : {}) } } } } : {}),
|
||||
...(this.failed ? { _meta: { jetbrains: { air: { version: 1, sessionFailure: { severity: "error", category: "service", title: "Pi provider request failed" } } } } } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -426,7 +426,7 @@ diff --git a/dist/paperclip-runtime.js b/dist/paperclip-runtime.js
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/dist/paperclip-runtime.js
|
||||
@@ -0,0 +1,256 @@
|
||||
@@ -0,0 +1,259 @@
|
||||
+/** Source for the helper embedded in patches/pi-acp@0.0.33.patch. */
|
||||
+import { StringDecoder } from "node:string_decoder";
|
||||
+import { isAbsolute, relative, resolve, sep } from "node:path";
|
||||
@@ -651,12 +651,15 @@ new file mode 100644
|
||||
+ accept(value ) {
|
||||
+ const message = record(value);
|
||||
+ if (message.role !== "assistant") return;
|
||||
+ this.failed = message.stopReason === "error";
|
||||
+ if (!message.usage || typeof message.usage !== "object") return;
|
||||
+ if (!message.usage || typeof message.usage !== "object") {
|
||||
+ this.failed = message.stopReason === "error";
|
||||
+ return;
|
||||
+ }
|
||||
+ const key = JSON.stringify([message.timestamp, message.id, message.usage, message.content]);
|
||||
+ if (this.seen.has(key)) return;
|
||||
+ if (this.seen.size >= 8192) throw new Error("Pi usage receipts exceed their bound");
|
||||
+ this.seen.add(key);
|
||||
+ this.failed = message.stopReason === "error";
|
||||
+ const usage = record(message.usage);
|
||||
+ const valid = (value ) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
||||
+ const fields = ["inputTokens", "outputTokens", "cachedReadTokens", "cachedWriteTokens"] ;
|
||||
@@ -678,7 +681,7 @@ new file mode 100644
|
||||
+
|
||||
+ response() {
|
||||
+ return {
|
||||
+ ...(this.observed ? { usage: { ...Object.fromEntries(Object.entries(this.total).filter(([name]) => !this.unknown.has(name ))), _meta: { paperclipPi: { provenance: "assistant_message_receipts", ...(this.costObserved && !this.costIncomplete ? { costUsd: this.cost } : {}) } } } } : {}),
|
||||
+ ...(this.observed ? { usage: { ...Object.fromEntries(Object.entries(this.total).filter(([name]) => !this.unknown.has(name ))), _meta: { paperclipPi: { provenance: "assistant_message_receipts", ...(this.costObserved && !this.costIncomplete ? { costUsd: this.cost, costSource: "pi_pricing_estimate" } : {}) } } } } : {}),
|
||||
+ ...(this.failed ? { _meta: { jetbrains: { air: { version: 1, sessionFailure: { severity: "error", category: "service", title: "Pi provider request failed" } } } } } : {}),
|
||||
+ };
|
||||
+ }
|
||||
|
||||
Reference in new issue
Block a user