@mcoda/agents 0.1.40 → 0.1.41
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpenAiAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/openai/OpenAiAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"OpenAiAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/openai/OpenAiAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAiKtG,KAAK,YAAY,GAAG,aAAa,GAAG;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC,CAAC;AAEF,qBAAa,aAAc,YAAW,YAAY;IAMpC,OAAO,CAAC,MAAM;IAL1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,SAAS,CAAsC;gBAEnC,MAAM,EAAE,YAAY;IAUlC,eAAe,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIpC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IA6GnC,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAwC5D,YAAY,CAAC,OAAO,EAAE,iBAAiB,GAAG,cAAc,CAAC,gBAAgB,EAAE,IAAI,EAAE,OAAO,CAAC;IAwFhG,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,SAAS;IAoBjB,OAAO,CAAC,oBAAoB;CAU7B"}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
+
import { parseUsageLimitError } from "../../AgentService/UsageLimitParser.js";
|
|
1
2
|
const DEFAULT_BASE_URL = "https://api.openai.com/v1";
|
|
3
|
+
const MAX_RESPONSE_DETAIL_CHARS = 500;
|
|
4
|
+
const RATE_LIMIT_HEADER_NAMES = [
|
|
5
|
+
"retry-after",
|
|
6
|
+
"x-ratelimit-reset-after",
|
|
7
|
+
"x-ratelimit-reset",
|
|
8
|
+
"x-ratelimit-reset-at",
|
|
9
|
+
"x-ratelimit-remaining",
|
|
10
|
+
];
|
|
2
11
|
const asString = (value) => (typeof value === "string" ? value : undefined);
|
|
3
12
|
const resolveString = (value) => {
|
|
4
13
|
const raw = asString(value)?.trim();
|
|
@@ -11,6 +20,37 @@ const normalizeBaseUrl = (value) => {
|
|
|
11
20
|
return undefined;
|
|
12
21
|
return str.endsWith("/") ? str.slice(0, -1) : str;
|
|
13
22
|
};
|
|
23
|
+
const buildRateLimitProbeMessage = (response, responseText) => {
|
|
24
|
+
const parts = [`openai_probe http ${response.status}`];
|
|
25
|
+
const retryAfter = response.headers.get("retry-after")?.trim();
|
|
26
|
+
if (retryAfter) {
|
|
27
|
+
const retryAfterSeconds = Number.parseInt(retryAfter, 10);
|
|
28
|
+
parts.push(Number.isFinite(retryAfterSeconds) && retryAfterSeconds > 0
|
|
29
|
+
? `Retry after ${retryAfterSeconds} seconds`
|
|
30
|
+
: `Retry after ${retryAfter}`);
|
|
31
|
+
}
|
|
32
|
+
for (const headerName of RATE_LIMIT_HEADER_NAMES) {
|
|
33
|
+
if (headerName === "retry-after")
|
|
34
|
+
continue;
|
|
35
|
+
const headerValue = response.headers.get(headerName)?.trim();
|
|
36
|
+
if (headerValue) {
|
|
37
|
+
parts.push(`${headerName}: ${headerValue}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const trimmedResponse = responseText.trim();
|
|
41
|
+
if (trimmedResponse) {
|
|
42
|
+
parts.push(trimmedResponse);
|
|
43
|
+
}
|
|
44
|
+
return parts.join(". ");
|
|
45
|
+
};
|
|
46
|
+
const resolveRetryAfterMs = (resetAt, nowMs) => {
|
|
47
|
+
if (!resetAt)
|
|
48
|
+
return undefined;
|
|
49
|
+
const timestampMs = Date.parse(resetAt);
|
|
50
|
+
if (!Number.isFinite(timestampMs))
|
|
51
|
+
return undefined;
|
|
52
|
+
return Math.max(0, timestampMs - nowMs);
|
|
53
|
+
};
|
|
14
54
|
const resolveBaseUrl = (config) => {
|
|
15
55
|
const anyConfig = config;
|
|
16
56
|
const agentConfig = config.agent?.config;
|
|
@@ -148,12 +188,38 @@ export class OpenAiAdapter {
|
|
|
148
188
|
body: JSON.stringify(this.buildHealthCheckBody(model)),
|
|
149
189
|
});
|
|
150
190
|
const responseText = await response.text().catch(() => "");
|
|
151
|
-
const
|
|
191
|
+
const checkedAtMs = Date.now();
|
|
192
|
+
const lastCheckedAt = new Date(checkedAtMs).toISOString();
|
|
193
|
+
const latencyMs = checkedAtMs - startedAt;
|
|
152
194
|
if (!response.ok) {
|
|
195
|
+
if (response.status === 429) {
|
|
196
|
+
const parsedLimit = parseUsageLimitError(new Error(buildRateLimitProbeMessage(response, responseText)), checkedAtMs);
|
|
197
|
+
return {
|
|
198
|
+
agentId: this.config.agent.id,
|
|
199
|
+
status: "healthy",
|
|
200
|
+
lastCheckedAt,
|
|
201
|
+
latencyMs,
|
|
202
|
+
details: {
|
|
203
|
+
adapter: "openai-api",
|
|
204
|
+
source: "openai_probe",
|
|
205
|
+
model,
|
|
206
|
+
baseUrl: url,
|
|
207
|
+
reason: "rate_limited",
|
|
208
|
+
transient: true,
|
|
209
|
+
rateLimited: true,
|
|
210
|
+
httpStatus: response.status,
|
|
211
|
+
response: responseText.slice(0, MAX_RESPONSE_DETAIL_CHARS),
|
|
212
|
+
resetAt: parsedLimit?.resetAt,
|
|
213
|
+
resetAtSource: parsedLimit?.resetAtSource,
|
|
214
|
+
retryAfterMs: resolveRetryAfterMs(parsedLimit?.resetAt, checkedAtMs),
|
|
215
|
+
windowTypes: parsedLimit?.windowTypes,
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
}
|
|
153
219
|
return {
|
|
154
220
|
agentId: this.config.agent.id,
|
|
155
|
-
status:
|
|
156
|
-
lastCheckedAt
|
|
221
|
+
status: "unreachable",
|
|
222
|
+
lastCheckedAt,
|
|
157
223
|
latencyMs,
|
|
158
224
|
details: {
|
|
159
225
|
adapter: "openai-api",
|
|
@@ -162,14 +228,14 @@ export class OpenAiAdapter {
|
|
|
162
228
|
baseUrl: url,
|
|
163
229
|
reason: "http_error",
|
|
164
230
|
httpStatus: response.status,
|
|
165
|
-
response: responseText.slice(0,
|
|
231
|
+
response: responseText.slice(0, MAX_RESPONSE_DETAIL_CHARS),
|
|
166
232
|
},
|
|
167
233
|
};
|
|
168
234
|
}
|
|
169
235
|
return {
|
|
170
236
|
agentId: this.config.agent.id,
|
|
171
237
|
status: "healthy",
|
|
172
|
-
lastCheckedAt
|
|
238
|
+
lastCheckedAt,
|
|
173
239
|
latencyMs,
|
|
174
240
|
details: {
|
|
175
241
|
adapter: "openai-api",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcoda/agents",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.41",
|
|
4
4
|
"description": "Agent registry and capabilities for mcoda.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"access": "public"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@mcoda/shared": "0.1.
|
|
34
|
-
"@mcoda/db": "0.1.
|
|
33
|
+
"@mcoda/shared": "0.1.41",
|
|
34
|
+
"@mcoda/db": "0.1.41"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"build": "tsc -p tsconfig.json",
|