@resolveio/server-lib 22.2.22 → 22.2.24
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/managers/openai-usage-ledger.manager.d.ts +1 -1
- package/managers/openai-usage-ledger.manager.js +4 -3
- package/managers/openai-usage-ledger.manager.js.map +1 -1
- package/managers/subscription.manager.d.ts +1 -0
- package/managers/subscription.manager.js +33 -7
- package/managers/subscription.manager.js.map +1 -1
- package/methods/ai-terminal.js +10 -17
- package/methods/ai-terminal.js.map +1 -1
- package/methods/mongo-explorer.js +2 -2
- package/methods/mongo-explorer.js.map +1 -1
- package/methods/report-builder.js +11 -13
- package/methods/report-builder.js.map +1 -1
- package/package.json +1 -1
|
@@ -96,13 +96,14 @@ var estimateCost = function (model, inputTokens, outputTokens) {
|
|
|
96
96
|
};
|
|
97
97
|
function recordOpenAIUsage(input) {
|
|
98
98
|
return __awaiter(this, void 0, void 0, function () {
|
|
99
|
-
var inputTokens, outputTokens, totalTokens, model, costEstimate;
|
|
99
|
+
var idClient, inputTokens, outputTokens, totalTokens, model, costEstimate;
|
|
100
100
|
return __generator(this, function (_a) {
|
|
101
101
|
switch (_a.label) {
|
|
102
102
|
case 0:
|
|
103
|
-
if (!input
|
|
103
|
+
if (!input) {
|
|
104
104
|
return [2 /*return*/];
|
|
105
105
|
}
|
|
106
|
+
idClient = String(input.id_client || '').trim();
|
|
106
107
|
inputTokens = toNumber(input.input_tokens);
|
|
107
108
|
outputTokens = toNumber(input.output_tokens);
|
|
108
109
|
totalTokens = toNumber(input.total_tokens);
|
|
@@ -114,7 +115,7 @@ function recordOpenAIUsage(input) {
|
|
|
114
115
|
? input.cost_estimate
|
|
115
116
|
: estimateCost(model, inputTokens, outputTokens);
|
|
116
117
|
return [4 /*yield*/, openai_usage_ledger_collection_1.OpenAIUsageLedger.insertOne({
|
|
117
|
-
id_client:
|
|
118
|
+
id_client: idClient,
|
|
118
119
|
timestamp: input.timestamp || new Date(),
|
|
119
120
|
model: model,
|
|
120
121
|
input_tokens: inputTokens,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/managers/openai-usage-ledger.manager.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFA,
|
|
1
|
+
{"version":3,"sources":["../../src/managers/openai-usage-ledger.manager.ts"],"names":[],"mappings":"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","file":"openai-usage-ledger.manager.js","sourcesContent":["import { round } from '../util/common';\nimport { ResolveIOServer } from '../resolveio-server-app';\nimport { OpenAIUsageLedger } from '../collections/openai-usage-ledger.collection';\n\nexport interface OpenAIUsageRecordInput {\n\tid_client?: string;\n\tmodel: string;\n\tinput_tokens: number;\n\toutput_tokens: number;\n\ttotal_tokens: number;\n\tbillable?: boolean;\n\tcategory?: string;\n\tid_request?: string;\n\tid_conversation?: string;\n\ttimestamp?: Date;\n\tcost_estimate?: number;\n}\n\ntype PricingConfig = {\n\tinputPer1k: number;\n\toutputPer1k: number;\n};\n\nconst toNumber = (value: any): number => {\n\tconst parsed = Number(value);\n\treturn Number.isFinite(parsed) ? parsed : 0;\n};\n\nconst normalizeModelKey = (value: string): string => {\n\treturn String(value || '').trim().toLowerCase();\n};\n\nconst parsePricingJson = (raw: string): Record<string, PricingConfig> => {\n\tif (!raw) {\n\t\treturn {};\n\t}\n\ttry {\n\t\tconst parsed = JSON.parse(raw);\n\t\tif (!parsed || typeof parsed !== 'object') {\n\t\t\treturn {};\n\t\t}\n\t\tconst out: Record<string, PricingConfig> = {};\n\t\tObject.keys(parsed).forEach((key) => {\n\t\t\tconst entry = parsed[key] || {};\n\t\t\tconst inputPer1k = toNumber(entry.inputPer1k ?? entry.input ?? entry.prompt ?? 0);\n\t\t\tconst outputPer1k = toNumber(entry.outputPer1k ?? entry.output ?? entry.completion ?? 0);\n\t\t\tif (inputPer1k || outputPer1k) {\n\t\t\t\tout[normalizeModelKey(key)] = { inputPer1k, outputPer1k };\n\t\t\t}\n\t\t});\n\t\treturn out;\n\t}\n\tcatch {\n\t\treturn {};\n\t}\n};\n\nconst resolvePricingConfig = (): { perModel: Record<string, PricingConfig>; defaultPricing: PricingConfig } => {\n\tconst config = ResolveIOServer.getServerConfig() || {};\n\tconst rawJson = String(config['OPENAI_MODEL_PRICING'] ?? process.env.OPENAI_MODEL_PRICING ?? '').trim();\n\tconst defaultInput = toNumber(config['OPENAI_COST_PER_1K_INPUT_TOKENS'] ?? process.env.OPENAI_COST_PER_1K_INPUT_TOKENS ?? 0);\n\tconst defaultOutput = toNumber(config['OPENAI_COST_PER_1K_OUTPUT_TOKENS'] ?? process.env.OPENAI_COST_PER_1K_OUTPUT_TOKENS ?? 0);\n\treturn {\n\t\tperModel: parsePricingJson(rawJson),\n\t\tdefaultPricing: { inputPer1k: defaultInput, outputPer1k: defaultOutput }\n\t};\n};\n\nconst estimateCost = (model: string, inputTokens: number, outputTokens: number): number => {\n\tconst { perModel, defaultPricing } = resolvePricingConfig();\n\tconst normalizedModel = normalizeModelKey(model);\n\tconst pricing = perModel[normalizedModel] || defaultPricing;\n\tif (!pricing.inputPer1k && !pricing.outputPer1k) {\n\t\treturn 0;\n\t}\n\tconst inputCost = (toNumber(inputTokens) / 1000) * pricing.inputPer1k;\n\tconst outputCost = (toNumber(outputTokens) / 1000) * pricing.outputPer1k;\n\treturn round(inputCost + outputCost, 6);\n};\n\nexport async function recordOpenAIUsage(input: OpenAIUsageRecordInput): Promise<void> {\n\tif (!input) {\n\t\treturn;\n\t}\n\tconst idClient = String(input.id_client || '').trim();\n\tconst inputTokens = toNumber(input.input_tokens);\n\tconst outputTokens = toNumber(input.output_tokens);\n\tconst totalTokens = toNumber(input.total_tokens);\n\tif (!totalTokens && (!inputTokens && !outputTokens)) {\n\t\treturn;\n\t}\n\tconst model = String(input.model || '').trim() || 'unknown';\n\tconst costEstimate = Number.isFinite(input.cost_estimate)\n\t\t? input.cost_estimate\n\t\t: estimateCost(model, inputTokens, outputTokens);\n\n\tawait OpenAIUsageLedger.insertOne({\n\t\tid_client: idClient,\n\t\ttimestamp: input.timestamp || new Date(),\n\t\tmodel,\n\t\tinput_tokens: inputTokens,\n\t\toutput_tokens: outputTokens,\n\t\ttotal_tokens: totalTokens || (inputTokens + outputTokens),\n\t\tcost_estimate: costEstimate,\n\t\tbillable: input.billable !== false,\n\t\tcategory: input.category || '',\n\t\tid_request: input.id_request || '',\n\t\tid_conversation: input.id_conversation || ''\n\t});\n}\n"]}
|
|
@@ -52,6 +52,7 @@ export declare class SubscriptionManager {
|
|
|
52
52
|
private _fullResyncPromise;
|
|
53
53
|
private readonly RESUME_TOKEN_COLLECTION;
|
|
54
54
|
private readonly RESUME_TOKEN_SAVE_INTERVAL_MS;
|
|
55
|
+
private readonly RESUME_TOKEN_AUTO_HEAL_RETRY_THRESHOLD;
|
|
55
56
|
private latencyBuffer;
|
|
56
57
|
private _latencyFlushInProgress;
|
|
57
58
|
private _latencyFlushPending;
|
|
@@ -164,6 +164,7 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
164
164
|
this._fullResyncPromise = null;
|
|
165
165
|
this.RESUME_TOKEN_COLLECTION = 'subscription-manager-resume-tokens';
|
|
166
166
|
this.RESUME_TOKEN_SAVE_INTERVAL_MS = 5000;
|
|
167
|
+
this.RESUME_TOKEN_AUTO_HEAL_RETRY_THRESHOLD = 2;
|
|
167
168
|
// Buffer to store throttled latency updates with timestamps
|
|
168
169
|
this.latencyBuffer = new Map();
|
|
169
170
|
this._latencyFlushInProgress = false;
|
|
@@ -1984,7 +1985,7 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
1984
1985
|
// Watch (tail) Mongo's operation log on the entire database (all insert/modify/delete will trigger this function)
|
|
1985
1986
|
SubscriptionManager.prototype.tailOpLog = function (resumeToken) {
|
|
1986
1987
|
return __awaiter(this, void 0, void 0, function () {
|
|
1987
|
-
var watchDatabases, pipeline, lastResumeToken_1,
|
|
1988
|
+
var watchDatabases, pipeline, lastResumeToken_1, startedWithResumeToken_1, sawChangeEvent_1, resumeTokenInvalidated_1, streamStartedAtMs_1, error_8, innerError_1, error_9;
|
|
1988
1989
|
var _this = this;
|
|
1989
1990
|
return __generator(this, function (_a) {
|
|
1990
1991
|
switch (_a.label) {
|
|
@@ -2035,14 +2036,17 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
2035
2036
|
},
|
|
2036
2037
|
},
|
|
2037
2038
|
];
|
|
2038
|
-
|
|
2039
|
+
startedWithResumeToken_1 = false;
|
|
2040
|
+
sawChangeEvent_1 = false;
|
|
2041
|
+
resumeTokenInvalidated_1 = false;
|
|
2042
|
+
streamStartedAtMs_1 = Date.now();
|
|
2039
2043
|
if (!resumeToken) return [3 /*break*/, 20];
|
|
2040
2044
|
lastResumeToken_1 = resumeToken;
|
|
2041
2045
|
_a.label = 4;
|
|
2042
2046
|
case 4:
|
|
2043
2047
|
_a.trys.push([4, 5, , 19]);
|
|
2044
2048
|
this._oplog$ = resolveio_server_app_1.ResolveIOServer.getMongoConnection().watch(pipeline, { resumeAfter: resumeToken, fullDocument: 'updateLookup' });
|
|
2045
|
-
|
|
2049
|
+
startedWithResumeToken_1 = true;
|
|
2046
2050
|
return [3 /*break*/, 19];
|
|
2047
2051
|
case 5:
|
|
2048
2052
|
error_8 = _a.sent();
|
|
@@ -2079,7 +2083,7 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
2079
2083
|
case 14:
|
|
2080
2084
|
_a.trys.push([14, 15, , 18]);
|
|
2081
2085
|
this._oplog$ = resolveio_server_app_1.ResolveIOServer.getMongoConnection().watch(pipeline, { fullDocument: 'updateLookup' });
|
|
2082
|
-
|
|
2086
|
+
startedWithResumeToken_1 = false;
|
|
2083
2087
|
return [3 /*break*/, 18];
|
|
2084
2088
|
case 15:
|
|
2085
2089
|
innerError_1 = _a.sent();
|
|
@@ -2112,12 +2116,14 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
2112
2116
|
return [2 /*return*/];
|
|
2113
2117
|
case 25: throw error_9;
|
|
2114
2118
|
case 26:
|
|
2115
|
-
console.log(new Date(), 'oplog started',
|
|
2119
|
+
console.log(new Date(), 'oplog started', startedWithResumeToken_1 ? '(resumeAfter)' : '');
|
|
2116
2120
|
this._oplog$.on('change', function (doc) { return __awaiter(_this, void 0, void 0, function () {
|
|
2117
2121
|
var collection, fullDocument, docId, flag, dependencyFlag;
|
|
2118
2122
|
return __generator(this, function (_a) {
|
|
2119
2123
|
switch (_a.label) {
|
|
2120
2124
|
case 0:
|
|
2125
|
+
sawChangeEvent_1 = true;
|
|
2126
|
+
this._oplogRetryCount = 0;
|
|
2121
2127
|
if (!doc.ns) return [3 /*break*/, 14];
|
|
2122
2128
|
if (this._enableDebug) {
|
|
2123
2129
|
console.log(new Date(), 'Oplog Hit', doc.ns);
|
|
@@ -2221,6 +2227,7 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
2221
2227
|
return [2 /*return*/];
|
|
2222
2228
|
case 5:
|
|
2223
2229
|
if (!this.isResumeTokenInvalid(error)) return [3 /*break*/, 7];
|
|
2230
|
+
resumeTokenInvalidated_1 = true;
|
|
2224
2231
|
return [4 /*yield*/, this.clearResumeToken()];
|
|
2225
2232
|
case 6:
|
|
2226
2233
|
_a.sent();
|
|
@@ -2247,15 +2254,34 @@ var SubscriptionManager = /** @class */ (function () {
|
|
|
2247
2254
|
});
|
|
2248
2255
|
}); });
|
|
2249
2256
|
this._oplog$.on('close', function () { return __awaiter(_this, void 0, void 0, function () {
|
|
2257
|
+
var retryThresholdReached, shouldAutoHealResumeToken;
|
|
2250
2258
|
return __generator(this, function (_a) {
|
|
2251
2259
|
switch (_a.label) {
|
|
2252
2260
|
case 0:
|
|
2253
2261
|
console.log(new Date(), 'oplog close');
|
|
2254
|
-
this.
|
|
2262
|
+
retryThresholdReached = this._oplogRetryCount >= this.RESUME_TOKEN_AUTO_HEAL_RETRY_THRESHOLD;
|
|
2263
|
+
shouldAutoHealResumeToken = startedWithResumeToken_1
|
|
2264
|
+
&& !!lastResumeToken_1
|
|
2265
|
+
&& !sawChangeEvent_1
|
|
2266
|
+
&& (resumeTokenInvalidated_1 || retryThresholdReached);
|
|
2267
|
+
if (!shouldAutoHealResumeToken) return [3 /*break*/, 2];
|
|
2268
|
+
return [4 /*yield*/, this.clearResumeToken()];
|
|
2269
|
+
case 1:
|
|
2270
|
+
_a.sent();
|
|
2271
|
+
lastResumeToken_1 = null;
|
|
2272
|
+
if (!resumeTokenInvalidated_1) {
|
|
2273
|
+
this.queueFullResync('oplog-resume-token-auto-heal');
|
|
2274
|
+
}
|
|
2275
|
+
console.log(new Date(), 'Sub Manager', 'Auto-healed stale oplog resume token', { retryCount: this._oplogRetryCount, streamLifetimeMs: Date.now() - streamStartedAtMs_1 });
|
|
2276
|
+
_a.label = 2;
|
|
2277
|
+
case 2:
|
|
2278
|
+
if (lastResumeToken_1) {
|
|
2279
|
+
this.queueResumeTokenSave(lastResumeToken_1, { force: true });
|
|
2280
|
+
}
|
|
2255
2281
|
this._oplog$.removeAllListeners();
|
|
2256
2282
|
this._oplog$ = null;
|
|
2257
2283
|
return [4 /*yield*/, this.tailOpLog(lastResumeToken_1)];
|
|
2258
|
-
case
|
|
2284
|
+
case 3:
|
|
2259
2285
|
_a.sent();
|
|
2260
2286
|
return [2 /*return*/];
|
|
2261
2287
|
}
|