@absolutejs/ai 0.0.22 → 0.0.23
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/ai/index.js +123 -3
- package/dist/ai/index.js.map +7 -6
- package/dist/ai/providers/anthropic.js +23 -3
- package/dist/ai/providers/anthropic.js.map +4 -4
- package/dist/ai/providers/gemini.js +23 -3
- package/dist/ai/providers/gemini.js.map +4 -4
- package/dist/ai/providers/ollama.js +23 -3
- package/dist/ai/providers/ollama.js.map +4 -4
- package/dist/ai/providers/openai.js +23 -3
- package/dist/ai/providers/openai.js.map +4 -4
- package/dist/ai/providers/openaiCompatible.js +23 -3
- package/dist/ai/providers/openaiCompatible.js.map +4 -4
- package/dist/ai/providers/openaiResponses.js +23 -3
- package/dist/ai/providers/openaiResponses.js.map +4 -4
- package/dist/src/ai/errors/providerError.d.ts +0 -1
- package/dist/src/ai/index.d.ts +3 -1
- package/dist/src/ai/providerStatusMonitor.d.ts +34 -0
- package/dist/src/ai/resilience.d.ts +24 -1
- package/package.json +1 -1
package/dist/ai/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __require = import.meta.require;
|
|
|
3
3
|
|
|
4
4
|
// src/ai/errors/providerError.ts
|
|
5
5
|
var PROVIDER_STATUS_PAGES = {
|
|
6
|
-
anthropic: "https://status.
|
|
6
|
+
anthropic: "https://status.claude.com",
|
|
7
7
|
gemini: "https://status.cloud.google.com",
|
|
8
8
|
google: "https://status.cloud.google.com",
|
|
9
9
|
openai: "https://status.openai.com"
|
|
@@ -101,6 +101,7 @@ var recordFor = (provider) => {
|
|
|
101
101
|
return existing;
|
|
102
102
|
const fresh = {
|
|
103
103
|
consecutiveFailures: 0,
|
|
104
|
+
external: null,
|
|
104
105
|
lastError: null,
|
|
105
106
|
lastFailureAt: null,
|
|
106
107
|
lastSuccessAt: null,
|
|
@@ -110,6 +111,15 @@ var recordFor = (provider) => {
|
|
|
110
111
|
health.set(provider, fresh);
|
|
111
112
|
return fresh;
|
|
112
113
|
};
|
|
114
|
+
var setProviderAvailability = (provider, status) => {
|
|
115
|
+
const record = recordFor(provider);
|
|
116
|
+
record.external = {
|
|
117
|
+
available: status.available,
|
|
118
|
+
checkedAt: Date.now(),
|
|
119
|
+
indicator: status.indicator ?? (status.available ? "operational" : "unknown"),
|
|
120
|
+
reason: status.reason ?? ""
|
|
121
|
+
};
|
|
122
|
+
};
|
|
113
123
|
var noteSuccess = (provider) => {
|
|
114
124
|
const record = recordFor(provider);
|
|
115
125
|
record.state = "closed";
|
|
@@ -134,7 +144,8 @@ var noteFailure = (provider, error) => {
|
|
|
134
144
|
};
|
|
135
145
|
var snapshot = (provider, record) => ({
|
|
136
146
|
consecutiveFailures: record.consecutiveFailures,
|
|
137
|
-
|
|
147
|
+
external: record.external,
|
|
148
|
+
healthy: record.state === "closed" && record.external?.available !== false,
|
|
138
149
|
lastError: record.lastError,
|
|
139
150
|
lastFailureAt: record.lastFailureAt,
|
|
140
151
|
lastSuccessAt: record.lastSuccessAt,
|
|
@@ -170,6 +181,15 @@ var sleep = (ms, signal) => new Promise((resolve, reject) => {
|
|
|
170
181
|
});
|
|
171
182
|
var circuitOpen = (provider) => {
|
|
172
183
|
const record = recordFor(provider);
|
|
184
|
+
if (record.external && !record.external.available) {
|
|
185
|
+
return new ProviderError({
|
|
186
|
+
message: `${provider} API is reported down${record.external.reason ? `: ${record.external.reason}` : ""}`,
|
|
187
|
+
provider,
|
|
188
|
+
retryable: true,
|
|
189
|
+
status: null,
|
|
190
|
+
type: record.external.indicator
|
|
191
|
+
});
|
|
192
|
+
}
|
|
173
193
|
if (record.state !== "open")
|
|
174
194
|
return null;
|
|
175
195
|
if (record.nextProbeAt !== null && Date.now() >= record.nextProbeAt) {
|
|
@@ -4124,11 +4144,110 @@ var createOAuth2ClientCredentialsTokenSource = (config2) => {
|
|
|
4124
4144
|
return inflight;
|
|
4125
4145
|
};
|
|
4126
4146
|
};
|
|
4147
|
+
// src/ai/providerStatusMonitor.ts
|
|
4148
|
+
var API_COMPONENT_BY_PROVIDER = {
|
|
4149
|
+
anthropic: "Claude API (api.anthropic.com)",
|
|
4150
|
+
openai: "Chat Completions"
|
|
4151
|
+
};
|
|
4152
|
+
var AVAILABLE_COMPONENT_STATUSES = new Set([
|
|
4153
|
+
"operational",
|
|
4154
|
+
"degraded_performance"
|
|
4155
|
+
]);
|
|
4156
|
+
var AVAILABLE_PAGE_INDICATORS = new Set(["none", "minor"]);
|
|
4157
|
+
var isRecord6 = (value) => typeof value === "object" && value !== null;
|
|
4158
|
+
var readString = (record, key) => typeof record[key] === "string" ? record[key] : "";
|
|
4159
|
+
var findComponentStatus = (body, componentName) => {
|
|
4160
|
+
if (!isRecord6(body) || !Array.isArray(body.components))
|
|
4161
|
+
return null;
|
|
4162
|
+
const match = body.components.filter(isRecord6).find((component) => readString(component, "name") === componentName);
|
|
4163
|
+
return match ? readString(match, "status") : null;
|
|
4164
|
+
};
|
|
4165
|
+
var readPageIndicator = (body) => {
|
|
4166
|
+
if (!isRecord6(body) || !isRecord6(body.status))
|
|
4167
|
+
return null;
|
|
4168
|
+
const indicator = readString(body.status, "indicator");
|
|
4169
|
+
return indicator === "" ? null : indicator;
|
|
4170
|
+
};
|
|
4171
|
+
var fetchJson = async (url, signal) => {
|
|
4172
|
+
const response = await fetch(url, { signal });
|
|
4173
|
+
if (!response.ok)
|
|
4174
|
+
throw new Error(`status fetch ${response.status}`);
|
|
4175
|
+
return response.json();
|
|
4176
|
+
};
|
|
4177
|
+
var unknownStatus = (provider) => ({
|
|
4178
|
+
available: true,
|
|
4179
|
+
checkedAt: Date.now(),
|
|
4180
|
+
componentName: null,
|
|
4181
|
+
indicator: "unknown",
|
|
4182
|
+
provider,
|
|
4183
|
+
reason: "",
|
|
4184
|
+
statusPageUrl: providerStatusPage(provider)
|
|
4185
|
+
});
|
|
4186
|
+
var fetchProviderApiStatus = async (provider, signal) => {
|
|
4187
|
+
const base = PROVIDER_STATUS_PAGES[provider];
|
|
4188
|
+
if (base === undefined)
|
|
4189
|
+
return unknownStatus(provider);
|
|
4190
|
+
try {
|
|
4191
|
+
const componentName = API_COMPONENT_BY_PROVIDER[provider] ?? null;
|
|
4192
|
+
if (componentName !== null) {
|
|
4193
|
+
const components = await fetchJson(`${base}/api/v2/components.json`, signal);
|
|
4194
|
+
const status = findComponentStatus(components, componentName);
|
|
4195
|
+
if (status !== null) {
|
|
4196
|
+
const available2 = AVAILABLE_COMPONENT_STATUSES.has(status);
|
|
4197
|
+
return {
|
|
4198
|
+
available: available2,
|
|
4199
|
+
checkedAt: Date.now(),
|
|
4200
|
+
componentName,
|
|
4201
|
+
indicator: status,
|
|
4202
|
+
provider,
|
|
4203
|
+
reason: available2 ? "" : `${status} on ${componentName}`,
|
|
4204
|
+
statusPageUrl: base
|
|
4205
|
+
};
|
|
4206
|
+
}
|
|
4207
|
+
}
|
|
4208
|
+
const summary = await fetchJson(`${base}/api/v2/status.json`, signal);
|
|
4209
|
+
const indicator = readPageIndicator(summary);
|
|
4210
|
+
if (indicator === null)
|
|
4211
|
+
return unknownStatus(provider);
|
|
4212
|
+
const available = AVAILABLE_PAGE_INDICATORS.has(indicator);
|
|
4213
|
+
return {
|
|
4214
|
+
available,
|
|
4215
|
+
checkedAt: Date.now(),
|
|
4216
|
+
componentName: null,
|
|
4217
|
+
indicator,
|
|
4218
|
+
provider,
|
|
4219
|
+
reason: available ? "" : `page status: ${indicator}`,
|
|
4220
|
+
statusPageUrl: base
|
|
4221
|
+
};
|
|
4222
|
+
} catch {
|
|
4223
|
+
return unknownStatus(provider);
|
|
4224
|
+
}
|
|
4225
|
+
};
|
|
4226
|
+
var startProviderStatusMonitor = (options) => {
|
|
4227
|
+
const providers = options?.providers ?? ["anthropic", "openai"];
|
|
4228
|
+
const intervalMs = options?.intervalMs ?? 60000;
|
|
4229
|
+
const tick = async () => {
|
|
4230
|
+
const results = await Promise.all(providers.map((provider) => fetchProviderApiStatus(provider)));
|
|
4231
|
+
for (const status of results) {
|
|
4232
|
+
setProviderAvailability(status.provider, {
|
|
4233
|
+
available: status.available,
|
|
4234
|
+
indicator: status.indicator,
|
|
4235
|
+
reason: status.reason
|
|
4236
|
+
});
|
|
4237
|
+
options?.onUpdate?.(status);
|
|
4238
|
+
}
|
|
4239
|
+
};
|
|
4240
|
+
tick();
|
|
4241
|
+
const timer = setInterval(() => void tick(), intervalMs);
|
|
4242
|
+
return () => clearInterval(timer);
|
|
4243
|
+
};
|
|
4127
4244
|
export {
|
|
4128
4245
|
xai,
|
|
4129
4246
|
withResilience,
|
|
4130
4247
|
streamAIToSSE,
|
|
4131
4248
|
streamAI,
|
|
4249
|
+
startProviderStatusMonitor,
|
|
4250
|
+
setProviderAvailability,
|
|
4132
4251
|
serverMessageToAction,
|
|
4133
4252
|
serializeAIMessage,
|
|
4134
4253
|
resolveRenderers,
|
|
@@ -4148,6 +4267,7 @@ export {
|
|
|
4148
4267
|
generateAIWithTools,
|
|
4149
4268
|
generateAI,
|
|
4150
4269
|
gemini,
|
|
4270
|
+
fetchProviderApiStatus,
|
|
4151
4271
|
deepseek,
|
|
4152
4272
|
createSyncConversationStore,
|
|
4153
4273
|
createOAuth2ClientCredentialsTokenSource,
|
|
@@ -4163,5 +4283,5 @@ export {
|
|
|
4163
4283
|
PROVIDER_STATUS_PAGES
|
|
4164
4284
|
};
|
|
4165
4285
|
|
|
4166
|
-
//# debugId=
|
|
4286
|
+
//# debugId=E077A15D83F1F94464756E2164756E21
|
|
4167
4287
|
//# sourceMappingURL=index.js.map
|