@fungi.computer/mule 0.2.1 → 0.2.2
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/README.md +4 -4
- package/dist/provider-status.js +25 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,10 +12,10 @@ npm install @fungi.computer/mule
|
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
The package ships ESM only and depends on `effect` and Pi
|
|
15
|
-
(`@earendil-works/pi-ai`) at runtime, plus `@fungi.computer/cairn`
|
|
16
|
-
does not require or install the MCP SDK. Consumers that type-check
|
|
17
|
-
declarations (`skipLibCheck: false`) must install Pi’s Google GenAI
|
|
18
|
-
declaration dependency themselves:
|
|
15
|
+
(`@earendil-works/pi-ai`) at runtime, plus TypeBox and `@fungi.computer/cairn`
|
|
16
|
+
for IDs. Mule does not require or install the MCP SDK. Consumers that type-check
|
|
17
|
+
dependency declarations (`skipLibCheck: false`) must install Pi’s Google GenAI
|
|
18
|
+
optional declaration dependency themselves:
|
|
19
19
|
|
|
20
20
|
```sh
|
|
21
21
|
npm install --save-dev @modelcontextprotocol/sdk
|
package/dist/provider-status.js
CHANGED
|
@@ -11,6 +11,12 @@ const decodeFailedEvent = Schema.decodeUnknownOption(Schema.Struct({
|
|
|
11
11
|
response: providerError,
|
|
12
12
|
}));
|
|
13
13
|
const decodeErrorReply = Schema.decodeUnknownOption(Schema.fromJsonString(providerError));
|
|
14
|
+
const decodeErrorEvent = Schema.decodeUnknownOption(Schema.Struct({
|
|
15
|
+
type: Schema.Literal("error"),
|
|
16
|
+
status: Schema.optional(Schema.Number.check(Schema.isInt(), Schema.isBetween({ minimum: 100, maximum: 599 }))),
|
|
17
|
+
code: Schema.optional(Schema.String),
|
|
18
|
+
error: Schema.optional(providerError.fields.error),
|
|
19
|
+
}));
|
|
14
20
|
const decodeBodyChunk = Schema.decodeUnknownSync(Schema.instanceOf(Uint8Array));
|
|
15
21
|
const errorBodyBytes = 16 * 1024;
|
|
16
22
|
const decodeSeconds = Schema.decodeUnknownOption(Schema.NumberFromString.check(Schema.isBetween({ minimum: 0, maximum: 60 })));
|
|
@@ -24,7 +30,9 @@ const decodeLimit = Schema.decodeUnknownOption(Schema.Literals([
|
|
|
24
30
|
const decodeRejected = Schema.decodeUnknownOption(Schema.Literal("rejected"));
|
|
25
31
|
const decodeExhausted = Schema.decodeUnknownOption(Schema.Literal("0"));
|
|
26
32
|
const decodeDate = Schema.decodeUnknownOption(Schema.DateTimeUtcFromString);
|
|
27
|
-
const decodeOverloaded = Schema.decodeUnknownOption(
|
|
33
|
+
const decodeOverloaded = Schema.decodeUnknownOption(
|
|
34
|
+
// https://docs.anthropic.com/en/api/errors#http-errors
|
|
35
|
+
Schema.Struct({
|
|
28
36
|
type: Schema.Literal("error"),
|
|
29
37
|
error: Schema.Struct({ type: Schema.Literal("overloaded_error") }),
|
|
30
38
|
}));
|
|
@@ -171,6 +179,22 @@ export function observeProviderStatus(options) {
|
|
|
171
179
|
if (Option.isSome(failed) &&
|
|
172
180
|
failed.value.response.error.code === usageLimitCode)
|
|
173
181
|
rejection = { code: "usage-limit-reached" };
|
|
182
|
+
// OpenAI's Responses error code, not an inference from overload prose:
|
|
183
|
+
// https://platform.openai.com/docs/api-reference/responses/object#responses/object-error
|
|
184
|
+
if (Option.isSome(failed) &&
|
|
185
|
+
failed.value.response.error.code === "server_error")
|
|
186
|
+
rejection = { code: "provider_unavailable" };
|
|
187
|
+
// WebSocket API errors retain HTTP status in the parsed event:
|
|
188
|
+
// https://developers.openai.com/api/docs/guides/websocket-mode/#handling-errors
|
|
189
|
+
const error = decodeErrorEvent(data);
|
|
190
|
+
if (Option.isSome(error)) {
|
|
191
|
+
const status = error.value.status;
|
|
192
|
+
if (status !== undefined && status >= 500)
|
|
193
|
+
rejection = { code: "provider_unavailable", status };
|
|
194
|
+
else if (status === undefined &&
|
|
195
|
+
(error.value.code ?? error.value.error?.code) === "server_error")
|
|
196
|
+
rejection = { code: "provider_unavailable" };
|
|
197
|
+
}
|
|
174
198
|
if (Option.isSome(decodeOverloaded(data)))
|
|
175
199
|
rejection = { code: "overloaded" };
|
|
176
200
|
await options?.onProviderStreamEvent?.(data, model);
|