@rulvar/openai 1.126.0 → 1.128.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.js +37 -35
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1137,6 +1137,7 @@ function reconcileStatement(invoice, statement, options) {
|
|
|
1137
1137
|
let statementTotalUsd;
|
|
1138
1138
|
let statementComponents;
|
|
1139
1139
|
let tokenMismatches = 0;
|
|
1140
|
+
let partialOverlap = false;
|
|
1140
1141
|
const tokenMismatchSample = [];
|
|
1141
1142
|
const rowsWithResponseId = billable.filter((row) => row.responseId !== void 0).length;
|
|
1142
1143
|
if (statement.kind === "requests") {
|
|
@@ -1166,50 +1167,51 @@ function reconcileStatement(invoice, statement, options) {
|
|
|
1166
1167
|
if (!carriesAnything) throw new ConfigError("statement reconciliation refused: no export row carries dollars, components, or usage; there is nothing to reconcile against");
|
|
1167
1168
|
const matched = [];
|
|
1168
1169
|
const matchedStatement = /* @__PURE__ */ new Set();
|
|
1170
|
+
const partialSegmentIds = /* @__PURE__ */ new Set();
|
|
1169
1171
|
for (const row of billable) {
|
|
1170
|
-
const
|
|
1171
|
-
|
|
1172
|
+
const rowIds = row.wireResponseIds !== void 0 && row.wireResponseIds.length > 0 ? row.wireResponseIds : row.responseId === void 0 ? [] : [row.responseId];
|
|
1173
|
+
const hits = rowIds.map((id) => byId.get(id)).filter((hit) => hit !== void 0);
|
|
1174
|
+
if (rowIds.length === 0 || hits.length !== rowIds.length) {
|
|
1172
1175
|
unmatchedRows += 1;
|
|
1173
1176
|
if (row.responseId !== void 0 && unmatchedIdSample.length < SAMPLE_CAP) unmatchedIdSample.push(row.responseId);
|
|
1177
|
+
for (const hit of hits) {
|
|
1178
|
+
partialSegmentIds.add(hit.responseId);
|
|
1179
|
+
partialOverlap = true;
|
|
1180
|
+
}
|
|
1174
1181
|
continue;
|
|
1175
1182
|
}
|
|
1176
|
-
matchedStatement.add(hit.responseId);
|
|
1183
|
+
for (const hit of hits) matchedStatement.add(hit.responseId);
|
|
1177
1184
|
matched.push(row);
|
|
1178
|
-
if (hit.usage !== void 0) {
|
|
1179
|
-
const
|
|
1180
|
-
[
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
],
|
|
1185
|
-
[
|
|
1186
|
-
"cachedInputTokens",
|
|
1187
|
-
hit.usage.cachedInputTokens,
|
|
1188
|
-
row.usage.cacheReadTokens
|
|
1189
|
-
],
|
|
1190
|
-
[
|
|
1191
|
-
"cacheWriteTokens",
|
|
1192
|
-
hit.usage.cacheWriteTokens,
|
|
1193
|
-
row.usage.cacheWriteTokens
|
|
1194
|
-
],
|
|
1195
|
-
[
|
|
1196
|
-
"outputTokens",
|
|
1197
|
-
hit.usage.outputTokens,
|
|
1198
|
-
row.usage.outputTokens
|
|
1199
|
-
]
|
|
1185
|
+
if (hits.length > 0 && hits.every((hit) => hit.usage !== void 0)) {
|
|
1186
|
+
const fields = [
|
|
1187
|
+
["inputTokens", row.usage.inputTokens],
|
|
1188
|
+
["cachedInputTokens", row.usage.cacheReadTokens],
|
|
1189
|
+
["cacheWriteTokens", row.usage.cacheWriteTokens],
|
|
1190
|
+
["outputTokens", row.usage.outputTokens]
|
|
1200
1191
|
];
|
|
1201
|
-
for (const [field,
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
field
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1192
|
+
for (const [field, ours] of fields) {
|
|
1193
|
+
let sum = 0;
|
|
1194
|
+
let present = 0;
|
|
1195
|
+
for (const hit of hits) {
|
|
1196
|
+
const value = hit.usage?.[field];
|
|
1197
|
+
if (value !== void 0) {
|
|
1198
|
+
sum += value;
|
|
1199
|
+
present += 1;
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
if (present === hits.length && sum !== ours) {
|
|
1203
|
+
tokenMismatches += 1;
|
|
1204
|
+
if (tokenMismatchSample.length < SAMPLE_CAP) tokenMismatchSample.push({
|
|
1205
|
+
responseId: row.responseId ?? rowIds[0] ?? "",
|
|
1206
|
+
field,
|
|
1207
|
+
ours,
|
|
1208
|
+
statement: sum
|
|
1209
|
+
});
|
|
1210
|
+
}
|
|
1209
1211
|
}
|
|
1210
1212
|
}
|
|
1211
1213
|
}
|
|
1212
|
-
for (const row of statement.rows) if (!matchedStatement.has(row.responseId)) {
|
|
1214
|
+
for (const row of statement.rows) if (!matchedStatement.has(row.responseId) && !partialSegmentIds.has(row.responseId)) {
|
|
1213
1215
|
statementOnlyRows += 1;
|
|
1214
1216
|
if (statementOnlyIdSample.length < SAMPLE_CAP) statementOnlyIdSample.push(row.responseId);
|
|
1215
1217
|
}
|
|
@@ -1321,7 +1323,7 @@ function reconcileStatement(invoice, statement, options) {
|
|
|
1321
1323
|
const tokensDivergent = tokenComparison === "verdict" && tokenMismatches > 0;
|
|
1322
1324
|
let verdict;
|
|
1323
1325
|
if (divergent.length > 0 || totalsDivergent || tokensDivergent) verdict = "divergence";
|
|
1324
|
-
else if (matchedRows === 0) verdict = "no-overlap";
|
|
1326
|
+
else if (matchedRows === 0 && !partialOverlap) verdict = "no-overlap";
|
|
1325
1327
|
else if (!coverageComplete) verdict = "partial-coverage";
|
|
1326
1328
|
else verdict = "match";
|
|
1327
1329
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulvar/openai",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.128.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.128.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.128.0"
|
|
33
33
|
},
|
|
34
34
|
"repository": {
|
|
35
35
|
"type": "git",
|