@resolveio/server-lib 22.0.10 → 22.0.12
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/methods/ai-terminal.js +398 -86
- package/methods/ai-terminal.js.map +1 -1
- package/methods/report-builder.js +34 -8
- package/methods/report-builder.js.map +1 -1
- package/package.json +1 -1
- package/services/codex-client.d.ts +24 -0
- package/services/codex-client.js +345 -23
- package/services/codex-client.js.map +1 -1
package/package.json
CHANGED
|
@@ -2,6 +2,8 @@ export interface CodexConfig {
|
|
|
2
2
|
apiKey?: string;
|
|
3
3
|
baseUrl?: string;
|
|
4
4
|
model?: string;
|
|
5
|
+
fallbackModel?: string;
|
|
6
|
+
fallbackModels?: string[];
|
|
5
7
|
maxRetries?: number;
|
|
6
8
|
retryDelayMs?: number;
|
|
7
9
|
}
|
|
@@ -12,6 +14,7 @@ export interface CodexRunOptions {
|
|
|
12
14
|
threadOptions?: CodexThreadOptions;
|
|
13
15
|
threadKey?: string;
|
|
14
16
|
reuseThread?: boolean;
|
|
17
|
+
fallbackModels?: string[];
|
|
15
18
|
onStreamEvent?: StreamEventHandler;
|
|
16
19
|
onStreamText?: StreamTextHandler;
|
|
17
20
|
}
|
|
@@ -29,6 +32,13 @@ export type CodexThreadOptions = {
|
|
|
29
32
|
};
|
|
30
33
|
export declare class CodexClient {
|
|
31
34
|
private static readonly PING_PROMPT;
|
|
35
|
+
private static readonly DEFAULT_FALLBACK_MODEL;
|
|
36
|
+
private static readonly MODEL_UNAVAILABLE_FALLBACK_FILE;
|
|
37
|
+
private static readonly DEFAULT_MODEL_UNAVAILABLE_TTL_MS;
|
|
38
|
+
private static readonly MIN_MODEL_UNAVAILABLE_TTL_MS;
|
|
39
|
+
private static readonly modelFallbackPreferences;
|
|
40
|
+
private static modelFallbackPreferencesLoaded;
|
|
41
|
+
private static modelFallbackPreferencesLoadPromise;
|
|
32
42
|
private codex;
|
|
33
43
|
private codexInit;
|
|
34
44
|
private readonly threadCache;
|
|
@@ -39,6 +49,7 @@ export declare class CodexClient {
|
|
|
39
49
|
private readonly defaultTimeoutMs;
|
|
40
50
|
private readonly pingEnabled;
|
|
41
51
|
private readonly pingTimeoutMs;
|
|
52
|
+
private readonly modelUnavailableTtlMs;
|
|
42
53
|
private readonly config;
|
|
43
54
|
private readonly defaultThreadOptions;
|
|
44
55
|
constructor(config: CodexConfig);
|
|
@@ -54,7 +65,20 @@ export declare class CodexClient {
|
|
|
54
65
|
private withTimeout;
|
|
55
66
|
private normalizeRetryCount;
|
|
56
67
|
private normalizeRetryDelay;
|
|
68
|
+
private resolveModelSequence;
|
|
69
|
+
private collectFallbackModels;
|
|
70
|
+
private normalizeModelList;
|
|
71
|
+
private applyModelOverride;
|
|
72
|
+
private isModelAvailabilityError;
|
|
57
73
|
private isRetryableError;
|
|
74
|
+
private normalizeOptionalString;
|
|
75
|
+
private resolveModelUnavailableTtlMs;
|
|
76
|
+
private ensureModelFallbackPreferencesLoaded;
|
|
77
|
+
private pruneModelFallbackPreferences;
|
|
78
|
+
private getModelFallbackPreference;
|
|
79
|
+
private rememberModelFallbackPreference;
|
|
80
|
+
private clearModelFallbackPreference;
|
|
81
|
+
private persistModelFallbackPreferences;
|
|
58
82
|
private sleep;
|
|
59
83
|
private ensureCodex;
|
|
60
84
|
private log;
|
package/services/codex-client.js
CHANGED
|
@@ -107,6 +107,7 @@ var CodexClient = /** @class */ (function () {
|
|
|
107
107
|
this.defaultTimeoutMs = this.resolveDefaultTimeoutMs();
|
|
108
108
|
this.pingEnabled = this.resolvePingEnabled();
|
|
109
109
|
this.pingTimeoutMs = this.resolvePingTimeoutMs();
|
|
110
|
+
this.modelUnavailableTtlMs = this.resolveModelUnavailableTtlMs();
|
|
110
111
|
this.config = config;
|
|
111
112
|
if (!this.config.apiKey) {
|
|
112
113
|
throw new Error('OPENAI_API_KEY is required for CodexClient');
|
|
@@ -115,46 +116,78 @@ var CodexClient = /** @class */ (function () {
|
|
|
115
116
|
}
|
|
116
117
|
CodexClient.prototype.run = function (prompt, options) {
|
|
117
118
|
return __awaiter(this, void 0, void 0, function () {
|
|
118
|
-
var maxRetries, retryDelayMs, attempt,
|
|
119
|
+
var maxRetries, retryDelayMs, lastError, modelSequence, modelIndex, model, nextModel, modelOptions, attempt, result_1, result, error_1, message, delay;
|
|
119
120
|
return __generator(this, function (_a) {
|
|
120
121
|
switch (_a.label) {
|
|
121
|
-
case 0:
|
|
122
|
+
case 0: return [4 /*yield*/, this.ensureModelFallbackPreferencesLoaded()];
|
|
123
|
+
case 1:
|
|
124
|
+
_a.sent();
|
|
122
125
|
maxRetries = this.normalizeRetryCount(this.config.maxRetries);
|
|
123
126
|
retryDelayMs = this.normalizeRetryDelay(this.config.retryDelayMs);
|
|
124
|
-
attempt = 0;
|
|
125
127
|
lastError = null;
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
case 1:
|
|
129
|
-
_a.sent();
|
|
128
|
+
modelSequence = this.resolveModelSequence(options);
|
|
129
|
+
modelIndex = 0;
|
|
130
130
|
_a.label = 2;
|
|
131
131
|
case 2:
|
|
132
|
-
if (!(
|
|
132
|
+
if (!(modelIndex < modelSequence.length)) return [3 /*break*/, 18];
|
|
133
|
+
model = modelSequence[modelIndex];
|
|
134
|
+
nextModel = modelSequence[modelIndex + 1];
|
|
135
|
+
modelOptions = this.applyModelOverride(options, model);
|
|
136
|
+
attempt = 0;
|
|
133
137
|
_a.label = 3;
|
|
134
138
|
case 3:
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
if (!(attempt <= maxRetries)) return [3 /*break*/, 17];
|
|
140
|
+
_a.label = 4;
|
|
141
|
+
case 4:
|
|
142
|
+
_a.trys.push([4, 12, , 16]);
|
|
143
|
+
this.log("run model=".concat(model || this.config.model || 'default', " attempt ").concat(attempt + 1, "/").concat(maxRetries + 1));
|
|
144
|
+
if (!(this.pingEnabled && !this.isPingPrompt(prompt))) return [3 /*break*/, 6];
|
|
145
|
+
return [4 /*yield*/, this.runPing(modelOptions === null || modelOptions === void 0 ? void 0 : modelOptions.threadOptions)];
|
|
146
|
+
case 5:
|
|
147
|
+
_a.sent();
|
|
148
|
+
_a.label = 6;
|
|
149
|
+
case 6:
|
|
150
|
+
if (!(this.streamEnabled && !this.isPingPrompt(prompt))) return [3 /*break*/, 9];
|
|
151
|
+
return [4 /*yield*/, this.runStreamedOnce(prompt, modelOptions)];
|
|
142
152
|
case 7:
|
|
153
|
+
result_1 = _a.sent();
|
|
154
|
+
return [4 /*yield*/, this.clearModelFallbackPreference(model)];
|
|
155
|
+
case 8:
|
|
156
|
+
_a.sent();
|
|
157
|
+
return [2 /*return*/, result_1];
|
|
158
|
+
case 9: return [4 /*yield*/, this.runOnce(prompt, modelOptions)];
|
|
159
|
+
case 10:
|
|
160
|
+
result = _a.sent();
|
|
161
|
+
return [4 /*yield*/, this.clearModelFallbackPreference(model)];
|
|
162
|
+
case 11:
|
|
163
|
+
_a.sent();
|
|
164
|
+
return [2 /*return*/, result];
|
|
165
|
+
case 12:
|
|
143
166
|
error_1 = _a.sent();
|
|
144
167
|
lastError = error_1;
|
|
145
168
|
message = error_1 instanceof Error ? error_1.message : String(error_1 || 'Unknown error');
|
|
146
|
-
this.log("run attempt ".concat(attempt + 1, " failed: ").concat(message));
|
|
169
|
+
this.log("run model=".concat(model || this.config.model || 'default', " attempt ").concat(attempt + 1, " failed: ").concat(message));
|
|
170
|
+
if (!(nextModel && this.isModelAvailabilityError(error_1))) return [3 /*break*/, 14];
|
|
171
|
+
return [4 /*yield*/, this.rememberModelFallbackPreference(model, nextModel)];
|
|
172
|
+
case 13:
|
|
173
|
+
_a.sent();
|
|
174
|
+
this.log("model unavailable; retrying with fallback model ".concat(nextModel));
|
|
175
|
+
return [3 /*break*/, 17];
|
|
176
|
+
case 14:
|
|
147
177
|
if (attempt >= maxRetries || !this.isRetryableError(error_1)) {
|
|
148
|
-
|
|
178
|
+
throw lastError;
|
|
149
179
|
}
|
|
150
180
|
delay = retryDelayMs * Math.pow(2, attempt);
|
|
151
181
|
return [4 /*yield*/, this.sleep(delay)];
|
|
152
|
-
case
|
|
182
|
+
case 15:
|
|
153
183
|
_a.sent();
|
|
154
184
|
attempt += 1;
|
|
155
|
-
return [3 /*break*/,
|
|
156
|
-
case
|
|
157
|
-
case
|
|
185
|
+
return [3 /*break*/, 16];
|
|
186
|
+
case 16: return [3 /*break*/, 3];
|
|
187
|
+
case 17:
|
|
188
|
+
modelIndex += 1;
|
|
189
|
+
return [3 /*break*/, 2];
|
|
190
|
+
case 18: throw lastError;
|
|
158
191
|
}
|
|
159
192
|
});
|
|
160
193
|
});
|
|
@@ -335,7 +368,7 @@ var CodexClient = /** @class */ (function () {
|
|
|
335
368
|
};
|
|
336
369
|
CodexClient.prototype.startThread = function (threadOptions_1, threadKey_1) {
|
|
337
370
|
return __awaiter(this, arguments, void 0, function (threadOptions, threadKey, reuseThread) {
|
|
338
|
-
var mergedOptions, cacheKey, existing, thread_1, thread;
|
|
371
|
+
var mergedOptions, effectiveModel, cacheKey, existing, thread_1, thread;
|
|
339
372
|
if (reuseThread === void 0) { reuseThread = true; }
|
|
340
373
|
return __generator(this, function (_a) {
|
|
341
374
|
switch (_a.label) {
|
|
@@ -343,6 +376,7 @@ var CodexClient = /** @class */ (function () {
|
|
|
343
376
|
case 1:
|
|
344
377
|
_a.sent();
|
|
345
378
|
mergedOptions = this.mergeThreadOptions(threadOptions);
|
|
379
|
+
effectiveModel = (mergedOptions === null || mergedOptions === void 0 ? void 0 : mergedOptions.model) || this.config.model || 'default';
|
|
346
380
|
cacheKey = this.buildThreadCacheKey(threadKey, mergedOptions);
|
|
347
381
|
if (reuseThread && cacheKey) {
|
|
348
382
|
existing = this.threadCache.get(cacheKey);
|
|
@@ -351,7 +385,7 @@ var CodexClient = /** @class */ (function () {
|
|
|
351
385
|
return [2 /*return*/, existing.thread];
|
|
352
386
|
}
|
|
353
387
|
}
|
|
354
|
-
this.log("startThread (model=".concat(
|
|
388
|
+
this.log("startThread (model=".concat(effectiveModel, ")"));
|
|
355
389
|
if (mergedOptions === null || mergedOptions === void 0 ? void 0 : mergedOptions.model) {
|
|
356
390
|
this.log("startThread options: ".concat(this.formatThreadOptions(mergedOptions)));
|
|
357
391
|
thread_1 = this.codex.startThread(mergedOptions);
|
|
@@ -658,6 +692,95 @@ var CodexClient = /** @class */ (function () {
|
|
|
658
692
|
}
|
|
659
693
|
return Math.max(100, Math.floor(value));
|
|
660
694
|
};
|
|
695
|
+
CodexClient.prototype.resolveModelSequence = function (options) {
|
|
696
|
+
var _this = this;
|
|
697
|
+
var _a;
|
|
698
|
+
var primary = this.normalizeOptionalString(((_a = options === null || options === void 0 ? void 0 : options.threadOptions) === null || _a === void 0 ? void 0 : _a.model) || this.config.model);
|
|
699
|
+
var fallbackModels = this.collectFallbackModels(options === null || options === void 0 ? void 0 : options.fallbackModels);
|
|
700
|
+
var sequence = [];
|
|
701
|
+
var push = function (value) {
|
|
702
|
+
var normalized = _this.normalizeOptionalString(value);
|
|
703
|
+
if (!normalized || sequence.includes(normalized)) {
|
|
704
|
+
return;
|
|
705
|
+
}
|
|
706
|
+
sequence.push(normalized);
|
|
707
|
+
};
|
|
708
|
+
var preferredFallback = this.getModelFallbackPreference(primary);
|
|
709
|
+
if (preferredFallback) {
|
|
710
|
+
push(preferredFallback);
|
|
711
|
+
this.log("sticky model fallback active: ".concat(primary, " -> ").concat(preferredFallback));
|
|
712
|
+
}
|
|
713
|
+
push(primary);
|
|
714
|
+
fallbackModels.forEach(push);
|
|
715
|
+
if (!fallbackModels.length && primary.toLowerCase().includes('codex')) {
|
|
716
|
+
push(CodexClient.DEFAULT_FALLBACK_MODEL);
|
|
717
|
+
}
|
|
718
|
+
if (!sequence.length) {
|
|
719
|
+
sequence.push('');
|
|
720
|
+
}
|
|
721
|
+
return sequence;
|
|
722
|
+
};
|
|
723
|
+
CodexClient.prototype.collectFallbackModels = function (runFallbackModels) {
|
|
724
|
+
var _this = this;
|
|
725
|
+
var models = [];
|
|
726
|
+
var push = function (value) {
|
|
727
|
+
var normalized = _this.normalizeOptionalString(value);
|
|
728
|
+
if (!normalized || models.includes(normalized)) {
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
models.push(normalized);
|
|
732
|
+
};
|
|
733
|
+
this.normalizeModelList(runFallbackModels).forEach(push);
|
|
734
|
+
this.normalizeModelList(this.config.fallbackModels).forEach(push);
|
|
735
|
+
push(this.config.fallbackModel);
|
|
736
|
+
this.normalizeModelList(process.env.AI_ASSISTANT_CODEX_FALLBACK_MODELS).forEach(push);
|
|
737
|
+
push(process.env.AI_ASSISTANT_CODEX_FALLBACK_MODEL);
|
|
738
|
+
this.normalizeModelList(process.env.AI_TERMINAL_CODEX_FALLBACK_MODELS).forEach(push);
|
|
739
|
+
push(process.env.AI_TERMINAL_CODEX_FALLBACK_MODEL);
|
|
740
|
+
this.normalizeModelList(process.env.AI_DASHBOARD_CODEX_FALLBACK_MODELS).forEach(push);
|
|
741
|
+
push(process.env.AI_DASHBOARD_CODEX_FALLBACK_MODEL);
|
|
742
|
+
return models;
|
|
743
|
+
};
|
|
744
|
+
CodexClient.prototype.normalizeModelList = function (value) {
|
|
745
|
+
var _this = this;
|
|
746
|
+
if (Array.isArray(value)) {
|
|
747
|
+
return value
|
|
748
|
+
.map(function (entry) { return _this.normalizeOptionalString(entry); })
|
|
749
|
+
.filter(Boolean);
|
|
750
|
+
}
|
|
751
|
+
var raw = this.normalizeOptionalString(value);
|
|
752
|
+
if (!raw) {
|
|
753
|
+
return [];
|
|
754
|
+
}
|
|
755
|
+
return raw
|
|
756
|
+
.split(',')
|
|
757
|
+
.map(function (entry) { return _this.normalizeOptionalString(entry); })
|
|
758
|
+
.filter(Boolean);
|
|
759
|
+
};
|
|
760
|
+
CodexClient.prototype.applyModelOverride = function (options, model) {
|
|
761
|
+
var nextThreadOptions = __assign({}, ((options === null || options === void 0 ? void 0 : options.threadOptions) || {}));
|
|
762
|
+
if (model) {
|
|
763
|
+
nextThreadOptions.model = model;
|
|
764
|
+
}
|
|
765
|
+
else {
|
|
766
|
+
delete nextThreadOptions.model;
|
|
767
|
+
}
|
|
768
|
+
return __assign(__assign({}, (options || {})), { threadOptions: nextThreadOptions });
|
|
769
|
+
};
|
|
770
|
+
CodexClient.prototype.isModelAvailabilityError = function (error) {
|
|
771
|
+
var message = error instanceof Error ? error.message : String(error || '');
|
|
772
|
+
var normalized = message.toLowerCase();
|
|
773
|
+
if (!normalized.includes('model')) {
|
|
774
|
+
return false;
|
|
775
|
+
}
|
|
776
|
+
if (/does not exist|not found|unknown model|invalid model|unsupported model|model_not_found|no such model/.test(normalized)) {
|
|
777
|
+
return true;
|
|
778
|
+
}
|
|
779
|
+
if (/not available|unavailable|not enabled|not allowed|do not have access|don't have access|insufficient permissions/.test(normalized)) {
|
|
780
|
+
return true;
|
|
781
|
+
}
|
|
782
|
+
return /404/.test(normalized) && /model/.test(normalized);
|
|
783
|
+
};
|
|
661
784
|
CodexClient.prototype.isRetryableError = function (error) {
|
|
662
785
|
var message = error instanceof Error ? error.message : String(error || '');
|
|
663
786
|
if (/Codex returned no completion content/i.test(message)) {
|
|
@@ -669,6 +792,198 @@ var CodexClient = /** @class */ (function () {
|
|
|
669
792
|
}
|
|
670
793
|
return /ECONNRESET|ETIMEDOUT|EAI_AGAIN|ENOTFOUND|fetch failed|timed out|timeout/i.test(message);
|
|
671
794
|
};
|
|
795
|
+
CodexClient.prototype.normalizeOptionalString = function (value) {
|
|
796
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
797
|
+
};
|
|
798
|
+
CodexClient.prototype.resolveModelUnavailableTtlMs = function () {
|
|
799
|
+
var raw = Number(process.env.AI_DASHBOARD_CODEX_MODEL_UNAVAILABLE_TTL_MS
|
|
800
|
+
|| process.env.AI_ASSISTANT_CODEX_MODEL_UNAVAILABLE_TTL_MS);
|
|
801
|
+
if (Number.isFinite(raw) && raw >= CodexClient.MIN_MODEL_UNAVAILABLE_TTL_MS) {
|
|
802
|
+
return Math.floor(raw);
|
|
803
|
+
}
|
|
804
|
+
return CodexClient.DEFAULT_MODEL_UNAVAILABLE_TTL_MS;
|
|
805
|
+
};
|
|
806
|
+
CodexClient.prototype.ensureModelFallbackPreferencesLoaded = function () {
|
|
807
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
808
|
+
var _this = this;
|
|
809
|
+
return __generator(this, function (_a) {
|
|
810
|
+
switch (_a.label) {
|
|
811
|
+
case 0:
|
|
812
|
+
if (CodexClient.modelFallbackPreferencesLoaded) {
|
|
813
|
+
this.pruneModelFallbackPreferences();
|
|
814
|
+
return [2 /*return*/];
|
|
815
|
+
}
|
|
816
|
+
if (!(CodexClient.modelFallbackPreferencesLoadPromise !== null)) return [3 /*break*/, 2];
|
|
817
|
+
return [4 /*yield*/, CodexClient.modelFallbackPreferencesLoadPromise];
|
|
818
|
+
case 1:
|
|
819
|
+
_a.sent();
|
|
820
|
+
this.pruneModelFallbackPreferences();
|
|
821
|
+
return [2 /*return*/];
|
|
822
|
+
case 2:
|
|
823
|
+
CodexClient.modelFallbackPreferencesLoadPromise = (function () { return __awaiter(_this, void 0, void 0, function () {
|
|
824
|
+
var raw, parsed, _a;
|
|
825
|
+
var _this = this;
|
|
826
|
+
return __generator(this, function (_b) {
|
|
827
|
+
switch (_b.label) {
|
|
828
|
+
case 0:
|
|
829
|
+
_b.trys.push([0, 2, 3, 4]);
|
|
830
|
+
return [4 /*yield*/, fs_1.promises.readFile(CodexClient.MODEL_UNAVAILABLE_FALLBACK_FILE, 'utf8')];
|
|
831
|
+
case 1:
|
|
832
|
+
raw = _b.sent();
|
|
833
|
+
parsed = JSON.parse(raw);
|
|
834
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
835
|
+
return [2 /*return*/];
|
|
836
|
+
}
|
|
837
|
+
Object.entries(parsed).forEach(function (_a) {
|
|
838
|
+
var _b = __read(_a, 2), model = _b[0], entry = _b[1];
|
|
839
|
+
var key = _this.normalizeOptionalString(model);
|
|
840
|
+
if (!key) {
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
var fallbackModel = _this.normalizeOptionalString(entry === null || entry === void 0 ? void 0 : entry.fallbackModel);
|
|
844
|
+
var expiresAt = Number(entry === null || entry === void 0 ? void 0 : entry.expiresAt);
|
|
845
|
+
var updatedAt = Number(entry === null || entry === void 0 ? void 0 : entry.updatedAt);
|
|
846
|
+
if (!fallbackModel || !Number.isFinite(expiresAt) || expiresAt <= Date.now()) {
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
CodexClient.modelFallbackPreferences.set(key, {
|
|
850
|
+
fallbackModel: fallbackModel,
|
|
851
|
+
expiresAt: Math.floor(expiresAt),
|
|
852
|
+
updatedAt: Number.isFinite(updatedAt) ? Math.floor(updatedAt) : Date.now()
|
|
853
|
+
});
|
|
854
|
+
});
|
|
855
|
+
return [3 /*break*/, 4];
|
|
856
|
+
case 2:
|
|
857
|
+
_a = _b.sent();
|
|
858
|
+
return [3 /*break*/, 4];
|
|
859
|
+
case 3:
|
|
860
|
+
CodexClient.modelFallbackPreferencesLoaded = true;
|
|
861
|
+
CodexClient.modelFallbackPreferencesLoadPromise = null;
|
|
862
|
+
return [7 /*endfinally*/];
|
|
863
|
+
case 4: return [2 /*return*/];
|
|
864
|
+
}
|
|
865
|
+
});
|
|
866
|
+
}); })();
|
|
867
|
+
return [4 /*yield*/, CodexClient.modelFallbackPreferencesLoadPromise];
|
|
868
|
+
case 3:
|
|
869
|
+
_a.sent();
|
|
870
|
+
this.pruneModelFallbackPreferences();
|
|
871
|
+
return [2 /*return*/];
|
|
872
|
+
}
|
|
873
|
+
});
|
|
874
|
+
});
|
|
875
|
+
};
|
|
876
|
+
CodexClient.prototype.pruneModelFallbackPreferences = function (now) {
|
|
877
|
+
if (now === void 0) { now = Date.now(); }
|
|
878
|
+
Array.from(CodexClient.modelFallbackPreferences.entries()).forEach(function (_a) {
|
|
879
|
+
var _b = __read(_a, 2), model = _b[0], entry = _b[1];
|
|
880
|
+
if (!entry || !Number.isFinite(entry.expiresAt) || entry.expiresAt <= now) {
|
|
881
|
+
CodexClient.modelFallbackPreferences.delete(model);
|
|
882
|
+
}
|
|
883
|
+
});
|
|
884
|
+
};
|
|
885
|
+
CodexClient.prototype.getModelFallbackPreference = function (model) {
|
|
886
|
+
var normalizedModel = this.normalizeOptionalString(model);
|
|
887
|
+
if (!normalizedModel) {
|
|
888
|
+
return '';
|
|
889
|
+
}
|
|
890
|
+
this.pruneModelFallbackPreferences();
|
|
891
|
+
var entry = CodexClient.modelFallbackPreferences.get(normalizedModel);
|
|
892
|
+
if (!entry || entry.expiresAt <= Date.now()) {
|
|
893
|
+
if (entry) {
|
|
894
|
+
CodexClient.modelFallbackPreferences.delete(normalizedModel);
|
|
895
|
+
}
|
|
896
|
+
return '';
|
|
897
|
+
}
|
|
898
|
+
return entry.fallbackModel;
|
|
899
|
+
};
|
|
900
|
+
CodexClient.prototype.rememberModelFallbackPreference = function (model, fallbackModel) {
|
|
901
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
902
|
+
var normalizedModel, normalizedFallback, now;
|
|
903
|
+
return __generator(this, function (_a) {
|
|
904
|
+
switch (_a.label) {
|
|
905
|
+
case 0:
|
|
906
|
+
normalizedModel = this.normalizeOptionalString(model);
|
|
907
|
+
normalizedFallback = this.normalizeOptionalString(fallbackModel);
|
|
908
|
+
if (!normalizedModel || !normalizedFallback || normalizedModel === normalizedFallback) {
|
|
909
|
+
return [2 /*return*/];
|
|
910
|
+
}
|
|
911
|
+
now = Date.now();
|
|
912
|
+
CodexClient.modelFallbackPreferences.set(normalizedModel, {
|
|
913
|
+
fallbackModel: normalizedFallback,
|
|
914
|
+
expiresAt: now + this.modelUnavailableTtlMs,
|
|
915
|
+
updatedAt: now
|
|
916
|
+
});
|
|
917
|
+
this.pruneModelFallbackPreferences(now);
|
|
918
|
+
return [4 /*yield*/, this.persistModelFallbackPreferences()];
|
|
919
|
+
case 1:
|
|
920
|
+
_a.sent();
|
|
921
|
+
return [2 /*return*/];
|
|
922
|
+
}
|
|
923
|
+
});
|
|
924
|
+
});
|
|
925
|
+
};
|
|
926
|
+
CodexClient.prototype.clearModelFallbackPreference = function (model) {
|
|
927
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
928
|
+
var normalizedModel;
|
|
929
|
+
return __generator(this, function (_a) {
|
|
930
|
+
switch (_a.label) {
|
|
931
|
+
case 0:
|
|
932
|
+
normalizedModel = this.normalizeOptionalString(model);
|
|
933
|
+
if (!normalizedModel) {
|
|
934
|
+
return [2 /*return*/];
|
|
935
|
+
}
|
|
936
|
+
if (!CodexClient.modelFallbackPreferences.has(normalizedModel)) {
|
|
937
|
+
return [2 /*return*/];
|
|
938
|
+
}
|
|
939
|
+
CodexClient.modelFallbackPreferences.delete(normalizedModel);
|
|
940
|
+
return [4 /*yield*/, this.persistModelFallbackPreferences()];
|
|
941
|
+
case 1:
|
|
942
|
+
_a.sent();
|
|
943
|
+
return [2 /*return*/];
|
|
944
|
+
}
|
|
945
|
+
});
|
|
946
|
+
});
|
|
947
|
+
};
|
|
948
|
+
CodexClient.prototype.persistModelFallbackPreferences = function () {
|
|
949
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
950
|
+
var _a, serialized, _b;
|
|
951
|
+
return __generator(this, function (_c) {
|
|
952
|
+
switch (_c.label) {
|
|
953
|
+
case 0:
|
|
954
|
+
this.pruneModelFallbackPreferences();
|
|
955
|
+
if (!!CodexClient.modelFallbackPreferences.size) return [3 /*break*/, 5];
|
|
956
|
+
_c.label = 1;
|
|
957
|
+
case 1:
|
|
958
|
+
_c.trys.push([1, 3, , 4]);
|
|
959
|
+
return [4 /*yield*/, fs_1.promises.unlink(CodexClient.MODEL_UNAVAILABLE_FALLBACK_FILE)];
|
|
960
|
+
case 2:
|
|
961
|
+
_c.sent();
|
|
962
|
+
return [3 /*break*/, 4];
|
|
963
|
+
case 3:
|
|
964
|
+
_a = _c.sent();
|
|
965
|
+
return [3 /*break*/, 4];
|
|
966
|
+
case 4: return [2 /*return*/];
|
|
967
|
+
case 5:
|
|
968
|
+
serialized = {};
|
|
969
|
+
CodexClient.modelFallbackPreferences.forEach(function (entry, model) {
|
|
970
|
+
serialized[model] = entry;
|
|
971
|
+
});
|
|
972
|
+
_c.label = 6;
|
|
973
|
+
case 6:
|
|
974
|
+
_c.trys.push([6, 8, , 9]);
|
|
975
|
+
return [4 /*yield*/, fs_1.promises.writeFile(CodexClient.MODEL_UNAVAILABLE_FALLBACK_FILE, JSON.stringify(serialized), 'utf8')];
|
|
976
|
+
case 7:
|
|
977
|
+
_c.sent();
|
|
978
|
+
return [3 /*break*/, 9];
|
|
979
|
+
case 8:
|
|
980
|
+
_b = _c.sent();
|
|
981
|
+
return [3 /*break*/, 9];
|
|
982
|
+
case 9: return [2 /*return*/];
|
|
983
|
+
}
|
|
984
|
+
});
|
|
985
|
+
});
|
|
986
|
+
};
|
|
672
987
|
CodexClient.prototype.sleep = function (ms) {
|
|
673
988
|
return __awaiter(this, void 0, void 0, function () {
|
|
674
989
|
return __generator(this, function (_a) {
|
|
@@ -984,6 +1299,13 @@ var CodexClient = /** @class */ (function () {
|
|
|
984
1299
|
});
|
|
985
1300
|
};
|
|
986
1301
|
CodexClient.PING_PROMPT = "Say 'pong'";
|
|
1302
|
+
CodexClient.DEFAULT_FALLBACK_MODEL = 'gpt-5.2-codex';
|
|
1303
|
+
CodexClient.MODEL_UNAVAILABLE_FALLBACK_FILE = path.join(os.tmpdir(), 'resolveio-codex-model-fallbacks.json');
|
|
1304
|
+
CodexClient.DEFAULT_MODEL_UNAVAILABLE_TTL_MS = 6 * 60 * 60 * 1000;
|
|
1305
|
+
CodexClient.MIN_MODEL_UNAVAILABLE_TTL_MS = 60 * 1000;
|
|
1306
|
+
CodexClient.modelFallbackPreferences = new Map();
|
|
1307
|
+
CodexClient.modelFallbackPreferencesLoaded = false;
|
|
1308
|
+
CodexClient.modelFallbackPreferencesLoadPromise = null;
|
|
987
1309
|
return CodexClient;
|
|
988
1310
|
}());
|
|
989
1311
|
exports.CodexClient = CodexClient;
|