@rulvar/openai 1.133.0 → 1.134.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +18 -3
- package/dist/index.js +25 -8
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -277,6 +277,18 @@ interface StatementReconciliation {
|
|
|
277
277
|
usageUnknownRows: number;
|
|
278
278
|
componentToleranceUsd: number;
|
|
279
279
|
verdict: "match" | "divergence" | "partial-coverage" | "no-overlap";
|
|
280
|
+
/**
|
|
281
|
+
* The settlement-grade composite, first class (RV1006): true exactly
|
|
282
|
+
* when the verdict is 'match' AND coverage is complete AND no row's
|
|
283
|
+
* usage is unknown AND no model went unpriced. A 'match' alone is
|
|
284
|
+
* not enough: an export can cover every KNOWN row to the cent while
|
|
285
|
+
* a usage-unknown attempt still holds unattributed money, and a safe
|
|
286
|
+
* consumer must not assemble this predicate by hand. The last two
|
|
287
|
+
* conditions overlap today's verdict semantics deliberately: the
|
|
288
|
+
* predicate states the full contract so it cannot drift apart from
|
|
289
|
+
* a future verdict refinement.
|
|
290
|
+
*/
|
|
291
|
+
settleable: boolean;
|
|
280
292
|
}
|
|
281
293
|
/**
|
|
282
294
|
* Reconciles the invoice against a normalized provider export. Pure and
|
|
@@ -285,9 +297,12 @@ interface StatementReconciliation {
|
|
|
285
297
|
* headline total with no rows), a request row without a response id, a
|
|
286
298
|
* duplicate response id (an ambiguous join), a request export whose
|
|
287
299
|
* rows carry neither dollars, components, nor usage, any non-finite or
|
|
288
|
-
* negative dollar amount, any non-integer or negative token count,
|
|
289
|
-
*
|
|
290
|
-
* be summed must refuse loudly, never verdict 'match' on NaN totals)
|
|
300
|
+
* negative dollar amount, any non-integer or negative token count, a
|
|
301
|
+
* non-finite or negative tolerance (RV903: a statement that cannot
|
|
302
|
+
* be summed must refuse loudly, never verdict 'match' on NaN totals),
|
|
303
|
+
* or a row whose usd and componentsUsd contradict each other beyond
|
|
304
|
+
* totalToleranceUsd (RV1005: an internally contradictory export is
|
|
305
|
+
* not evidence either).
|
|
291
306
|
*/
|
|
292
307
|
declare function reconcileStatement(invoice: {
|
|
293
308
|
rows: readonly InvoiceRow[];
|
package/dist/index.js
CHANGED
|
@@ -1108,9 +1108,12 @@ function assertTokenCount(where, field, value) {
|
|
|
1108
1108
|
* headline total with no rows), a request row without a response id, a
|
|
1109
1109
|
* duplicate response id (an ambiguous join), a request export whose
|
|
1110
1110
|
* rows carry neither dollars, components, nor usage, any non-finite or
|
|
1111
|
-
* negative dollar amount, any non-integer or negative token count,
|
|
1112
|
-
*
|
|
1113
|
-
* be summed must refuse loudly, never verdict 'match' on NaN totals)
|
|
1111
|
+
* negative dollar amount, any non-integer or negative token count, a
|
|
1112
|
+
* non-finite or negative tolerance (RV903: a statement that cannot
|
|
1113
|
+
* be summed must refuse loudly, never verdict 'match' on NaN totals),
|
|
1114
|
+
* or a row whose usd and componentsUsd contradict each other beyond
|
|
1115
|
+
* totalToleranceUsd (RV1005: an internally contradictory export is
|
|
1116
|
+
* not evidence either).
|
|
1114
1117
|
*/
|
|
1115
1118
|
function reconcileStatement(invoice, statement, options) {
|
|
1116
1119
|
for (const [name, value] of [["componentToleranceUsd", options.componentToleranceUsd], ["totalToleranceUsd", options.totalToleranceUsd]]) if (value !== void 0 && (!Number.isFinite(value) || value < 0)) throw new ConfigError(`statement reconciliation refused: ${name} ${String(value)} is not a finite nonnegative dollar tolerance`);
|
|
@@ -1136,6 +1139,8 @@ function reconcileStatement(invoice, statement, options) {
|
|
|
1136
1139
|
const statementOnlyIdSample = [];
|
|
1137
1140
|
let statementTotalUsd;
|
|
1138
1141
|
let statementComponents;
|
|
1142
|
+
let matchedStatementRows = 0;
|
|
1143
|
+
let matchedUsdRows = 0;
|
|
1139
1144
|
let tokenMismatches = 0;
|
|
1140
1145
|
let partialOverlap = false;
|
|
1141
1146
|
const tokenMismatchSample = [];
|
|
@@ -1148,9 +1153,18 @@ function reconcileStatement(invoice, statement, options) {
|
|
|
1148
1153
|
if (byId.has(row.responseId)) throw new ConfigError(`statement reconciliation refused: duplicate response id '${row.responseId}' in the export makes the join ambiguous`);
|
|
1149
1154
|
const where = `row '${row.responseId}'`;
|
|
1150
1155
|
if (row.usd !== void 0) assertStatementUsd(where, "usd", row.usd);
|
|
1151
|
-
if (row.componentsUsd !== void 0)
|
|
1152
|
-
|
|
1153
|
-
|
|
1156
|
+
if (row.componentsUsd !== void 0) {
|
|
1157
|
+
let componentsSum = 0;
|
|
1158
|
+
let componentsSeen = 0;
|
|
1159
|
+
for (const component of COMPONENTS) {
|
|
1160
|
+
const usd = row.componentsUsd[component];
|
|
1161
|
+
if (usd !== void 0) {
|
|
1162
|
+
assertStatementUsd(where, `componentsUsd.${component}`, usd);
|
|
1163
|
+
componentsSum += usd;
|
|
1164
|
+
componentsSeen += 1;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
if (row.usd !== void 0 && componentsSeen > 0 && Math.abs(row.usd - componentsSum) > totalToleranceUsd) throw new ConfigError(`statement reconciliation refused: ${where} carries usd ${String(row.usd)} and a component split summing to ${String(componentsSum)}, claims that contradict each other beyond the ${String(totalToleranceUsd)} totals tolerance; an export whose own total disagrees with its own components is not evidence: normalize it to one dollar claim per row or fix the export`);
|
|
1154
1168
|
}
|
|
1155
1169
|
if (row.usage !== void 0) for (const field of [
|
|
1156
1170
|
"inputTokens",
|
|
@@ -1222,7 +1236,9 @@ function reconcileStatement(invoice, statement, options) {
|
|
|
1222
1236
|
statementComponents = /* @__PURE__ */ new Map();
|
|
1223
1237
|
for (const row of statement.rows) {
|
|
1224
1238
|
if (!matchedStatement.has(row.responseId)) continue;
|
|
1239
|
+
matchedStatementRows += 1;
|
|
1225
1240
|
if (row.usd !== void 0) {
|
|
1241
|
+
matchedUsdRows += 1;
|
|
1226
1242
|
totalSeen = true;
|
|
1227
1243
|
total += row.usd;
|
|
1228
1244
|
}
|
|
@@ -1318,7 +1334,7 @@ function reconcileStatement(invoice, statement, options) {
|
|
|
1318
1334
|
}
|
|
1319
1335
|
const divergent = components.filter((line) => line.divergent).sort((a, b) => Math.abs(b.deltaUsd ?? 0) - Math.abs(a.deltaUsd ?? 0));
|
|
1320
1336
|
const totalsDelta = statementTotalUsd === void 0 ? void 0 : statementTotalUsd - ourUsd;
|
|
1321
|
-
const totalsDivergent =
|
|
1337
|
+
const totalsDivergent = unpricedModels.size === 0 && (statement.kind === "requests" ? matchedUsdRows === matchedStatementRows : statementOnlyRows === 0 && components.every((line) => line.statementUsd !== void 0)) && totalsDelta !== void 0 && Math.abs(totalsDelta) > totalToleranceUsd;
|
|
1322
1338
|
const coverageComplete = unmatchedRows === 0 && statementOnlyRows === 0 && unpricedModels.size === 0 && (statement.kind === "categories" || matchedRows === rowsWithResponseId && rowsWithResponseId === billable.length) && (statement.kind === "requests" || components.every((line) => line.statementUsd !== void 0));
|
|
1323
1339
|
const tokensDivergent = tokenComparison === "verdict" && tokenMismatches > 0;
|
|
1324
1340
|
let verdict;
|
|
@@ -1350,7 +1366,8 @@ function reconcileStatement(invoice, statement, options) {
|
|
|
1350
1366
|
unpricedModels: [...unpricedModels].sort(),
|
|
1351
1367
|
usageUnknownRows,
|
|
1352
1368
|
componentToleranceUsd,
|
|
1353
|
-
verdict
|
|
1369
|
+
verdict,
|
|
1370
|
+
settleable: verdict === "match" && coverageComplete && usageUnknownRows === 0 && unpricedModels.size === 0
|
|
1354
1371
|
};
|
|
1355
1372
|
}
|
|
1356
1373
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulvar/openai",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.134.0",
|
|
4
4
|
"description": "Rulvar first-class provider adapter for the OpenAI Responses API, plus the openaiCompatible factory.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -23,13 +23,13 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"openai": "^6.49.0",
|
|
26
|
-
"@rulvar/core": "1.
|
|
26
|
+
"@rulvar/core": "1.134.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/node": "^22.20.1",
|
|
30
30
|
"tsdown": "^0.22.14",
|
|
31
31
|
"typescript": "~6.0.3",
|
|
32
|
-
"@rulvar/testing": "1.
|
|
32
|
+
"@rulvar/testing": "1.134.0"
|
|
33
33
|
},
|
|
34
34
|
"repository": {
|
|
35
35
|
"type": "git",
|