@resolveio/server-lib 22.3.146 → 22.3.148

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.
@@ -82,6 +82,55 @@ var schema = {
82
82
  id_conversation: {
83
83
  type: String,
84
84
  optional: true
85
+ },
86
+ usage_source: {
87
+ type: String,
88
+ optional: true
89
+ },
90
+ usage_surface: {
91
+ type: String,
92
+ optional: true
93
+ },
94
+ usage_phase: {
95
+ type: String,
96
+ optional: true
97
+ },
98
+ cost_basis: {
99
+ type: String,
100
+ optional: true
101
+ },
102
+ id_run: {
103
+ type: String,
104
+ optional: true
105
+ },
106
+ id_job: {
107
+ type: String,
108
+ optional: true
109
+ },
110
+ id_app: {
111
+ type: String,
112
+ optional: true
113
+ },
114
+ id_ticket: {
115
+ type: String,
116
+ optional: true
117
+ },
118
+ is_manual: {
119
+ type: Boolean,
120
+ optional: true
121
+ },
122
+ is_untracked: {
123
+ type: Boolean,
124
+ optional: true
125
+ },
126
+ untracked_reason: {
127
+ type: String,
128
+ optional: true
129
+ },
130
+ metadata: {
131
+ type: Object,
132
+ optional: true,
133
+ blackbox: true
85
134
  }
86
135
  };
87
136
  var model = mongo_manager_1.MongoManagerModel.create({
@@ -115,6 +164,21 @@ setTimeout(function () { return __awaiter(void 0, void 0, void 0, function () {
115
164
  _a.sent();
116
165
  return [4 /*yield*/, exports.OpenAIUsageLedger.createIndex({ id_request: 1 })];
117
166
  case 3:
167
+ _a.sent();
168
+ return [4 /*yield*/, exports.OpenAIUsageLedger.createIndex({ id_run: 1, timestamp: -1 })];
169
+ case 4:
170
+ _a.sent();
171
+ return [4 /*yield*/, exports.OpenAIUsageLedger.createIndex({ id_job: 1, timestamp: -1 })];
172
+ case 5:
173
+ _a.sent();
174
+ return [4 /*yield*/, exports.OpenAIUsageLedger.createIndex({ id_app: 1, timestamp: -1 })];
175
+ case 6:
176
+ _a.sent();
177
+ return [4 /*yield*/, exports.OpenAIUsageLedger.createIndex({ id_ticket: 1, timestamp: -1 })];
178
+ case 7:
179
+ _a.sent();
180
+ return [4 /*yield*/, exports.OpenAIUsageLedger.createIndex({ usage_source: 1, usage_surface: 1, timestamp: -1 })];
181
+ case 8:
118
182
  _a.sent();
119
183
  return [2 /*return*/];
120
184
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/collections/openai-usage-ledger.collection.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2DAA8D;AAG9D,IAAM,MAAM,GAAQ;IACnB,GAAG,EAAE;QACJ,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,SAAS,EAAE;QACV,IAAI,EAAE,MAAM;KACZ;IACD,SAAS,EAAE;QACV,IAAI,EAAE,IAAI;KACV;IACD,KAAK,EAAE;QACN,IAAI,EAAE,MAAM;KACZ;IACD,YAAY,EAAE;QACb,IAAI,EAAE,MAAM;KACZ;IACD,mBAAmB,EAAE;QACpB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,aAAa,EAAE;QACd,IAAI,EAAE,MAAM;KACZ;IACD,YAAY,EAAE;QACb,IAAI,EAAE,MAAM;KACZ;IACD,aAAa,EAAE;QACd,IAAI,EAAE,MAAM;KACZ;IACD,QAAQ,EAAE;QACT,IAAI,EAAE,OAAO;KACb;IACD,QAAQ,EAAE;QACT,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,UAAU,EAAE;QACX,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,eAAe,EAAE;QAChB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;CACD,CAAC;AAEF,IAAM,KAAK,GAAG,iCAAiB,CAAC,MAAM,CAAyB;IAC9D,cAAc,EAAE,qBAAqB;IACrC,MAAM,QAAA;IACN,oBAAoB,EAAE,KAAK;IAC3B,gBAAgB,EAAE,KAAK;IACvB,yBAAyB,EAAE,EAAE;IAC7B,UAAU,EAAE,KAAK;IACjB,UAAU,EAAE,KAAK;IACjB,WAAW,EAAE,IAAI;IACjB,iBAAiB,EAAE;QAClB,UAAU,EAAE;YACX,SAAS,EAAE,WAAW;YACtB,SAAS,EAAE,WAAW;YACtB,WAAW,EAAE,OAAO;SACpB;QACD,kBAAkB,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG;KACtC;IACD,SAAS,EAAE,IAAI;CACf,CAAC,CAAC;AAEU,QAAA,iBAAiB,GAAG,KAAK,CAAC,eAAe,CAAC;AAEvD,UAAU,CAAC;;;oBACV,qBAAM,yBAAiB,CAAC,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAA;;gBAApE,SAAoE,CAAC;gBACrE,qBAAM,yBAAiB,CAAC,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAA;;gBAA1E,SAA0E,CAAC;gBAC3E,qBAAM,yBAAiB,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,EAAA;;gBAAtD,SAAsD,CAAC;;;;KACvD,EAAE,IAAI,CAAC,CAAC","file":"openai-usage-ledger.collection.js","sourcesContent":["import { MongoManagerModel } from '../managers/mongo.manager';\nimport { OpenAIUsageLedgerModel } from '../models/openai-usage-ledger.model';\n\nconst schema: any = {\n\t_id: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\tid_client: {\n\t\ttype: String\n\t},\n\ttimestamp: {\n\t\ttype: Date\n\t},\n\tmodel: {\n\t\ttype: String\n\t},\n\tinput_tokens: {\n\t\ttype: Number\n\t},\n\tcached_input_tokens: {\n\t\ttype: Number,\n\t\toptional: true\n\t},\n\toutput_tokens: {\n\t\ttype: Number\n\t},\n\ttotal_tokens: {\n\t\ttype: Number\n\t},\n\tcost_estimate: {\n\t\ttype: Number\n\t},\n\tbillable: {\n\t\ttype: Boolean\n\t},\n\tcategory: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\tid_request: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\tid_conversation: {\n\t\ttype: String,\n\t\toptional: true\n\t}\n};\n\nconst model = MongoManagerModel.create<OpenAIUsageLedgerModel>({\n\tcollectionName: 'openai-usage-ledger',\n\tschema,\n\tuseVersionCollection: false,\n\tuseReportBuilder: false,\n\treportBuilderLookupTables: [],\n\ttimestamps: false,\n\tcreateLogs: false,\n\tcheckSchema: true,\n\tcollectionOptions: {\n\t\ttimeseries: {\n\t\t\ttimeField: 'timestamp',\n\t\t\tmetaField: 'id_client',\n\t\t\tgranularity: 'hours'\n\t\t},\n\t\texpireAfterSeconds: 60 * 60 * 24 * 365\n\t},\n\tskipCache: true\n});\n\nexport const OpenAIUsageLedger = model.collection_main;\n\nsetTimeout(async () => {\n\tawait OpenAIUsageLedger.createIndex({ id_client: 1, timestamp: -1 });\n\tawait OpenAIUsageLedger.createIndex({ id_conversation: 1, timestamp: -1 });\n\tawait OpenAIUsageLedger.createIndex({ id_request: 1 });\n}, 5000);\n"]}
1
+ {"version":3,"sources":["../../src/collections/openai-usage-ledger.collection.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2DAA8D;AAG9D,IAAM,MAAM,GAAQ;IACnB,GAAG,EAAE;QACJ,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,SAAS,EAAE;QACV,IAAI,EAAE,MAAM;KACZ;IACD,SAAS,EAAE;QACV,IAAI,EAAE,IAAI;KACV;IACD,KAAK,EAAE;QACN,IAAI,EAAE,MAAM;KACZ;IACD,YAAY,EAAE;QACb,IAAI,EAAE,MAAM;KACZ;IACD,mBAAmB,EAAE;QACpB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,aAAa,EAAE;QACd,IAAI,EAAE,MAAM;KACZ;IACD,YAAY,EAAE;QACb,IAAI,EAAE,MAAM;KACZ;IACD,aAAa,EAAE;QACd,IAAI,EAAE,MAAM;KACZ;IACD,QAAQ,EAAE;QACT,IAAI,EAAE,OAAO;KACb;IACD,QAAQ,EAAE;QACT,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,UAAU,EAAE;QACX,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,eAAe,EAAE;QAChB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,YAAY,EAAE;QACb,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,aAAa,EAAE;QACd,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,WAAW,EAAE;QACZ,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,UAAU,EAAE;QACX,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,MAAM,EAAE;QACP,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,MAAM,EAAE;QACP,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,MAAM,EAAE;QACP,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,SAAS,EAAE;QACV,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,SAAS,EAAE;QACV,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,IAAI;KACd;IACD,YAAY,EAAE;QACb,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,IAAI;KACd;IACD,gBAAgB,EAAE;QACjB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;KACd;IACD,QAAQ,EAAE;QACT,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,IAAI;QACd,QAAQ,EAAE,IAAI;KACd;CACD,CAAC;AAEF,IAAM,KAAK,GAAG,iCAAiB,CAAC,MAAM,CAAyB;IAC9D,cAAc,EAAE,qBAAqB;IACrC,MAAM,QAAA;IACN,oBAAoB,EAAE,KAAK;IAC3B,gBAAgB,EAAE,KAAK;IACvB,yBAAyB,EAAE,EAAE;IAC7B,UAAU,EAAE,KAAK;IACjB,UAAU,EAAE,KAAK;IACjB,WAAW,EAAE,IAAI;IACjB,iBAAiB,EAAE;QAClB,UAAU,EAAE;YACX,SAAS,EAAE,WAAW;YACtB,SAAS,EAAE,WAAW;YACtB,WAAW,EAAE,OAAO;SACpB;QACD,kBAAkB,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG;KACtC;IACD,SAAS,EAAE,IAAI;CACf,CAAC,CAAC;AAEU,QAAA,iBAAiB,GAAG,KAAK,CAAC,eAAe,CAAC;AAEvD,UAAU,CAAC;;;oBACV,qBAAM,yBAAiB,CAAC,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAA;;gBAApE,SAAoE,CAAC;gBACrE,qBAAM,yBAAiB,CAAC,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAA;;gBAA1E,SAA0E,CAAC;gBAC3E,qBAAM,yBAAiB,CAAC,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,EAAA;;gBAAtD,SAAsD,CAAC;gBACvD,qBAAM,yBAAiB,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAA;;gBAAjE,SAAiE,CAAC;gBAClE,qBAAM,yBAAiB,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAA;;gBAAjE,SAAiE,CAAC;gBAClE,qBAAM,yBAAiB,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAA;;gBAAjE,SAAiE,CAAC;gBAClE,qBAAM,yBAAiB,CAAC,WAAW,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAA;;gBAApE,SAAoE,CAAC;gBACrE,qBAAM,yBAAiB,CAAC,WAAW,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAA;;gBAAzF,SAAyF,CAAC;;;;KAC1F,EAAE,IAAI,CAAC,CAAC","file":"openai-usage-ledger.collection.js","sourcesContent":["import { MongoManagerModel } from '../managers/mongo.manager';\nimport { OpenAIUsageLedgerModel } from '../models/openai-usage-ledger.model';\n\nconst schema: any = {\n\t_id: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\tid_client: {\n\t\ttype: String\n\t},\n\ttimestamp: {\n\t\ttype: Date\n\t},\n\tmodel: {\n\t\ttype: String\n\t},\n\tinput_tokens: {\n\t\ttype: Number\n\t},\n\tcached_input_tokens: {\n\t\ttype: Number,\n\t\toptional: true\n\t},\n\toutput_tokens: {\n\t\ttype: Number\n\t},\n\ttotal_tokens: {\n\t\ttype: Number\n\t},\n\tcost_estimate: {\n\t\ttype: Number\n\t},\n\tbillable: {\n\t\ttype: Boolean\n\t},\n\tcategory: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\tid_request: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\tid_conversation: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\tusage_source: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\tusage_surface: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\tusage_phase: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\tcost_basis: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\tid_run: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\tid_job: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\tid_app: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\tid_ticket: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\tis_manual: {\n\t\ttype: Boolean,\n\t\toptional: true\n\t},\n\tis_untracked: {\n\t\ttype: Boolean,\n\t\toptional: true\n\t},\n\tuntracked_reason: {\n\t\ttype: String,\n\t\toptional: true\n\t},\n\tmetadata: {\n\t\ttype: Object,\n\t\toptional: true,\n\t\tblackbox: true\n\t}\n};\n\nconst model = MongoManagerModel.create<OpenAIUsageLedgerModel>({\n\tcollectionName: 'openai-usage-ledger',\n\tschema,\n\tuseVersionCollection: false,\n\tuseReportBuilder: false,\n\treportBuilderLookupTables: [],\n\ttimestamps: false,\n\tcreateLogs: false,\n\tcheckSchema: true,\n\tcollectionOptions: {\n\t\ttimeseries: {\n\t\t\ttimeField: 'timestamp',\n\t\t\tmetaField: 'id_client',\n\t\t\tgranularity: 'hours'\n\t\t},\n\t\texpireAfterSeconds: 60 * 60 * 24 * 365\n\t},\n\tskipCache: true\n});\n\nexport const OpenAIUsageLedger = model.collection_main;\n\nsetTimeout(async () => {\n\tawait OpenAIUsageLedger.createIndex({ id_client: 1, timestamp: -1 });\n\tawait OpenAIUsageLedger.createIndex({ id_conversation: 1, timestamp: -1 });\n\tawait OpenAIUsageLedger.createIndex({ id_request: 1 });\n\tawait OpenAIUsageLedger.createIndex({ id_run: 1, timestamp: -1 });\n\tawait OpenAIUsageLedger.createIndex({ id_job: 1, timestamp: -1 });\n\tawait OpenAIUsageLedger.createIndex({ id_app: 1, timestamp: -1 });\n\tawait OpenAIUsageLedger.createIndex({ id_ticket: 1, timestamp: -1 });\n\tawait OpenAIUsageLedger.createIndex({ usage_source: 1, usage_surface: 1, timestamp: -1 });\n}, 5000);\n"]}
@@ -1,3 +1,4 @@
1
+ import { OpenAIUsageCostBasis, OpenAIUsageSource, OpenAIUsageSurface } from '../models/openai-usage-ledger.model';
1
2
  export { estimateOpenAIUsageCost, OpenAIUsagePricingConfig } from '../util/openai-usage-cost';
2
3
  export interface OpenAIUsageRecordInput {
3
4
  id_client?: string;
@@ -12,5 +13,18 @@ export interface OpenAIUsageRecordInput {
12
13
  id_conversation?: string;
13
14
  timestamp?: Date;
14
15
  cost_estimate?: number;
16
+ usage_source?: OpenAIUsageSource | string;
17
+ usage_surface?: OpenAIUsageSurface | string;
18
+ usage_phase?: string;
19
+ cost_basis?: OpenAIUsageCostBasis | string;
20
+ id_run?: string;
21
+ id_job?: string;
22
+ id_app?: string;
23
+ id_ticket?: string;
24
+ is_manual?: boolean;
25
+ is_untracked?: boolean;
26
+ untracked_reason?: string;
27
+ metadata?: Record<string, any>;
15
28
  }
16
29
  export declare function recordOpenAIUsage(input: OpenAIUsageRecordInput): Promise<void>;
30
+ export declare function recordManualCodexUsageEstimate(input: Omit<OpenAIUsageRecordInput, 'usage_source' | 'is_manual'>): Promise<void>;
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
14
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
15
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -38,6 +49,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
38
49
  Object.defineProperty(exports, "__esModule", { value: true });
39
50
  exports.estimateOpenAIUsageCost = void 0;
40
51
  exports.recordOpenAIUsage = recordOpenAIUsage;
52
+ exports.recordManualCodexUsageEstimate = recordManualCodexUsageEstimate;
41
53
  var openai_usage_ledger_collection_1 = require("../collections/openai-usage-ledger.collection");
42
54
  var openai_usage_cost_1 = require("../util/openai-usage-cost");
43
55
  var openai_usage_cost_2 = require("../util/openai-usage-cost");
@@ -46,6 +58,19 @@ var toNumber = function (value) {
46
58
  var parsed = Number(value);
47
59
  return Number.isFinite(parsed) ? parsed : 0;
48
60
  };
61
+ var cleanText = function (value, max) {
62
+ if (max === void 0) { max = 240; }
63
+ if (value === undefined || value === null) {
64
+ return '';
65
+ }
66
+ return String(value).trim().slice(0, max);
67
+ };
68
+ var cleanMetadata = function (value) {
69
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
70
+ return undefined;
71
+ }
72
+ return __assign({}, value);
73
+ };
49
74
  function recordOpenAIUsage(input) {
50
75
  return __awaiter(this, void 0, void 0, function () {
51
76
  var idClient, inputTokens, cachedInputTokens, outputTokens, totalTokens, model, normalizedInputCostEstimate, costEstimate;
@@ -78,9 +103,21 @@ function recordOpenAIUsage(input) {
78
103
  total_tokens: totalTokens || (inputTokens + outputTokens),
79
104
  cost_estimate: costEstimate,
80
105
  billable: input.billable !== false,
81
- category: input.category || '',
82
- id_request: input.id_request || '',
83
- id_conversation: input.id_conversation || ''
106
+ category: cleanText(input.category, 160),
107
+ id_request: cleanText(input.id_request, 240),
108
+ id_conversation: cleanText(input.id_conversation, 240),
109
+ usage_source: cleanText(input.usage_source, 80) || 'unknown',
110
+ usage_surface: cleanText(input.usage_surface, 80) || 'unknown',
111
+ usage_phase: cleanText(input.usage_phase, 120),
112
+ cost_basis: cleanText(input.cost_basis, 80) || (normalizedInputCostEstimate > 0 ? 'provider_usage' : 'estimated_tokens'),
113
+ id_run: cleanText(input.id_run, 240),
114
+ id_job: cleanText(input.id_job, 240),
115
+ id_app: cleanText(input.id_app, 240),
116
+ id_ticket: cleanText(input.id_ticket, 240),
117
+ is_manual: input.is_manual === true || cleanText(input.usage_source, 80) === 'manual_codex',
118
+ is_untracked: input.is_untracked === true,
119
+ untracked_reason: cleanText(input.untracked_reason, 500),
120
+ metadata: cleanMetadata(input.metadata)
84
121
  })];
85
122
  case 1:
86
123
  _a.sent();
@@ -89,5 +126,17 @@ function recordOpenAIUsage(input) {
89
126
  });
90
127
  });
91
128
  }
129
+ function recordManualCodexUsageEstimate(input) {
130
+ return __awaiter(this, void 0, void 0, function () {
131
+ return __generator(this, function (_a) {
132
+ switch (_a.label) {
133
+ case 0: return [4 /*yield*/, recordOpenAIUsage(__assign(__assign({}, input), { usage_source: 'manual_codex', usage_surface: input.usage_surface || 'manual', cost_basis: input.cost_basis || 'manual_estimate', is_manual: true, is_untracked: input.is_untracked !== false, untracked_reason: input.untracked_reason || 'Manual Codex session was outside the managed runner telemetry path.' }))];
134
+ case 1:
135
+ _a.sent();
136
+ return [2 /*return*/];
137
+ }
138
+ });
139
+ });
140
+ }
92
141
 
93
142
  //# sourceMappingURL=openai-usage-ledger.manager.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/managers/openai-usage-ledger.manager.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,8CAgCC;AAxDD,gGAAkF;AAClF,+DAAoE;AACpE,+DAA8F;AAArF,4HAAA,uBAAuB,OAAA;AAiBhC,IAAM,QAAQ,GAAG,UAAC,KAAU;IAC3B,IAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC,CAAC;AAEF,SAAsB,iBAAiB,CAAC,KAA6B;;;;;;oBACpE,IAAI,CAAC,KAAK,EAAE,CAAC;wBACZ,sBAAO;oBACR,CAAC;oBACK,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;oBAChD,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;oBAC3C,iBAAiB,GAAG,QAAQ,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;oBACxD,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;oBAC7C,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;oBACjD,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;wBACrD,sBAAO;oBACR,CAAC;oBACK,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;oBACtD,2BAA2B,GAAG,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;oBAC5D,YAAY,GAAG,2BAA2B,GAAG,CAAC;wBACnD,CAAC,CAAC,2BAA2B;wBAC7B,CAAC,CAAC,IAAA,2CAAuB,EAAC,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,iBAAiB,CAAC,CAAC;oBAEhF,qBAAM,kDAAiB,CAAC,SAAS,CAAC;4BACjC,SAAS,EAAE,QAAQ;4BACnB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE;4BACxC,KAAK,OAAA;4BACL,YAAY,EAAE,WAAW;4BACzB,mBAAmB,EAAE,iBAAiB;4BACtC,aAAa,EAAE,YAAY;4BAC3B,YAAY,EAAE,WAAW,IAAI,CAAC,WAAW,GAAG,YAAY,CAAC;4BACzD,aAAa,EAAE,YAAY;4BAC3B,QAAQ,EAAE,KAAK,CAAC,QAAQ,KAAK,KAAK;4BAClC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,EAAE;4BAC9B,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,EAAE;4BAClC,eAAe,EAAE,KAAK,CAAC,eAAe,IAAI,EAAE;yBAC5C,CAAC,EAAA;;oBAbF,SAaE,CAAC;;;;;CACH","file":"openai-usage-ledger.manager.js","sourcesContent":["import { OpenAIUsageLedger } from '../collections/openai-usage-ledger.collection';\nimport { estimateOpenAIUsageCost } from '../util/openai-usage-cost';\nexport { estimateOpenAIUsageCost, OpenAIUsagePricingConfig } from '../util/openai-usage-cost';\n\nexport interface OpenAIUsageRecordInput {\n\tid_client?: string;\n\tmodel: string;\n\tinput_tokens: number;\n\tcached_input_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\nconst toNumber = (value: any): number => {\n\tconst parsed = Number(value);\n\treturn Number.isFinite(parsed) ? parsed : 0;\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 cachedInputTokens = toNumber(input.cached_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 normalizedInputCostEstimate = toNumber(input.cost_estimate);\n\tconst costEstimate = normalizedInputCostEstimate > 0\n\t\t? normalizedInputCostEstimate\n\t\t: estimateOpenAIUsageCost(model, inputTokens, outputTokens, cachedInputTokens);\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\tcached_input_tokens: cachedInputTokens,\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"]}
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 { OpenAIUsageLedger } from '../collections/openai-usage-ledger.collection';\nimport {\n\tOpenAIUsageCostBasis,\n\tOpenAIUsageSource,\n\tOpenAIUsageSurface\n} from '../models/openai-usage-ledger.model';\nimport { estimateOpenAIUsageCost } from '../util/openai-usage-cost';\nexport { estimateOpenAIUsageCost, OpenAIUsagePricingConfig } from '../util/openai-usage-cost';\n\nexport interface OpenAIUsageRecordInput {\n\tid_client?: string;\n\tmodel: string;\n\tinput_tokens: number;\n\tcached_input_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\tusage_source?: OpenAIUsageSource | string;\n\tusage_surface?: OpenAIUsageSurface | string;\n\tusage_phase?: string;\n\tcost_basis?: OpenAIUsageCostBasis | string;\n\tid_run?: string;\n\tid_job?: string;\n\tid_app?: string;\n\tid_ticket?: string;\n\tis_manual?: boolean;\n\tis_untracked?: boolean;\n\tuntracked_reason?: string;\n\tmetadata?: Record<string, any>;\n}\n\nconst toNumber = (value: any): number => {\n\tconst parsed = Number(value);\n\treturn Number.isFinite(parsed) ? parsed : 0;\n};\n\nconst cleanText = (value: any, max = 240): string => {\n\tif (value === undefined || value === null) {\n\t\treturn '';\n\t}\n\treturn String(value).trim().slice(0, max);\n};\n\nconst cleanMetadata = (value: any): Record<string, any> | undefined => {\n\tif (!value || typeof value !== 'object' || Array.isArray(value)) {\n\t\treturn undefined;\n\t}\n\treturn { ...value };\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 cachedInputTokens = toNumber(input.cached_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 normalizedInputCostEstimate = toNumber(input.cost_estimate);\n\tconst costEstimate = normalizedInputCostEstimate > 0\n\t\t? normalizedInputCostEstimate\n\t\t: estimateOpenAIUsageCost(model, inputTokens, outputTokens, cachedInputTokens);\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\tcached_input_tokens: cachedInputTokens,\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: cleanText(input.category, 160),\n\t\tid_request: cleanText(input.id_request, 240),\n\t\tid_conversation: cleanText(input.id_conversation, 240),\n\t\tusage_source: cleanText(input.usage_source, 80) || 'unknown',\n\t\tusage_surface: cleanText(input.usage_surface, 80) || 'unknown',\n\t\tusage_phase: cleanText(input.usage_phase, 120),\n\t\tcost_basis: cleanText(input.cost_basis, 80) || (normalizedInputCostEstimate > 0 ? 'provider_usage' : 'estimated_tokens'),\n\t\tid_run: cleanText(input.id_run, 240),\n\t\tid_job: cleanText(input.id_job, 240),\n\t\tid_app: cleanText(input.id_app, 240),\n\t\tid_ticket: cleanText(input.id_ticket, 240),\n\t\tis_manual: input.is_manual === true || cleanText(input.usage_source, 80) === 'manual_codex',\n\t\tis_untracked: input.is_untracked === true,\n\t\tuntracked_reason: cleanText(input.untracked_reason, 500),\n\t\tmetadata: cleanMetadata(input.metadata)\n\t});\n}\n\nexport async function recordManualCodexUsageEstimate(input: Omit<OpenAIUsageRecordInput, 'usage_source' | 'is_manual'>): Promise<void> {\n\tawait recordOpenAIUsage({\n\t\t...input,\n\t\tusage_source: 'manual_codex',\n\t\tusage_surface: input.usage_surface || 'manual',\n\t\tcost_basis: input.cost_basis || 'manual_estimate',\n\t\tis_manual: true,\n\t\tis_untracked: input.is_untracked !== false,\n\t\tuntracked_reason: input.untracked_reason || 'Manual Codex session was outside the managed runner telemetry path.'\n\t});\n}\n"]}
@@ -1517,7 +1517,16 @@ function executeAiTerminalRun(payload, context) {
1517
1517
  output_tokens: usage.outputTokens,
1518
1518
  total_tokens: usage.totalTokens,
1519
1519
  category: 'ai-terminal',
1520
- id_conversation: conversation._id
1520
+ id_conversation: conversation._id,
1521
+ usage_source: 'ai_assistant',
1522
+ usage_surface: 'assistant',
1523
+ usage_phase: 'chat',
1524
+ cost_basis: 'estimated_tokens',
1525
+ id_app: String((conversation === null || conversation === void 0 ? void 0 : conversation.id_app) || ''),
1526
+ metadata: {
1527
+ conversationId: conversation._id,
1528
+ requestId: input.request_id || ''
1529
+ }
1521
1530
  })];
1522
1531
  case 19:
1523
1532
  _b.sent();
@@ -1625,7 +1634,14 @@ function executeAiFormPatch(payload, context) {
1625
1634
  input_tokens: usage.inputTokens,
1626
1635
  output_tokens: usage.outputTokens,
1627
1636
  total_tokens: usage.totalTokens,
1628
- category: 'ai-form'
1637
+ category: 'ai-form',
1638
+ usage_source: 'ai_assistant',
1639
+ usage_surface: 'assistant',
1640
+ usage_phase: 'form_patch',
1641
+ cost_basis: 'estimated_tokens',
1642
+ metadata: {
1643
+ route: input.route || ''
1644
+ }
1629
1645
  })];
1630
1646
  case 3:
1631
1647
  _b.sent();
@@ -3047,7 +3063,18 @@ function executeAiAssistantCodexRun(payload, context) {
3047
3063
  total_tokens: finalUsage.total_tokens,
3048
3064
  category: 'ai-terminal-codex',
3049
3065
  id_request: requestId || undefined,
3050
- id_conversation: conversation._id
3066
+ id_conversation: conversation._id,
3067
+ usage_source: 'ai_assistant',
3068
+ usage_surface: 'assistant',
3069
+ usage_phase: 'codex_query',
3070
+ cost_basis: 'estimated_tokens',
3071
+ id_app: String((conversation === null || conversation === void 0 ? void 0 : conversation.id_app) || ''),
3072
+ metadata: {
3073
+ conversationId: conversation._id,
3074
+ requestId: requestId || '',
3075
+ plannerUsed: plannerUsed,
3076
+ toolMode: toolTelemetry.mode
3077
+ }
3051
3078
  })];
3052
3079
  case 74:
3053
3080
  _22.sent();