@ethisyscore/extension-runtime 1.137.0 → 1.138.0
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/{MockPluginStorage-BndTX2RR.d.ts → MockPluginStorage-DF3DL1dI.d.ts} +25 -1
- package/dist/{MockPluginStorage-BM3bq99B.d.cts → MockPluginStorage-QKfz8CMt.d.cts} +25 -1
- package/dist/host/index.cjs +29 -2
- package/dist/host/index.cjs.map +1 -1
- package/dist/host/index.js +29 -2
- package/dist/host/index.js.map +1 -1
- package/dist/mock-host/cli.cjs +196 -129
- package/dist/mock-host/cli.cjs.map +1 -1
- package/dist/mock-host/cli.d.cts +1 -1
- package/dist/mock-host/cli.d.ts +1 -1
- package/dist/mock-host/cli.js +196 -129
- package/dist/mock-host/cli.js.map +1 -1
- package/dist/mock-host/index.cjs +40 -0
- package/dist/mock-host/index.cjs.map +1 -1
- package/dist/mock-host/index.d.cts +2 -2
- package/dist/mock-host/index.d.ts +2 -2
- package/dist/mock-host/index.js +40 -0
- package/dist/mock-host/index.js.map +1 -1
- package/dist/plugin/index.cjs +31 -2
- package/dist/plugin/index.cjs.map +1 -1
- package/dist/plugin/index.d.cts +17 -2
- package/dist/plugin/index.d.ts +17 -2
- package/dist/plugin/index.js +31 -2
- package/dist/plugin/index.js.map +1 -1
- package/package.json +2 -2
package/dist/plugin/index.d.cts
CHANGED
|
@@ -47,13 +47,18 @@ declare const PLUGIN_STORAGE_PATH_MAX_LENGTH = 128;
|
|
|
47
47
|
* - `unsupported_type`: the file's extension is not on the allow-list, or the declared type does
|
|
48
48
|
* not match it (client-side check, or a server 415).
|
|
49
49
|
* - `timeout`: the upload was too slow or missed the server's deadline (408). Retryable.
|
|
50
|
-
* - `busy`: the
|
|
50
|
+
* - `busy`: the server refused the upload for capacity (503). The message says which limit: too
|
|
51
|
+
* many uploads in progress for this user or organisation, all of the server's upload slots taken,
|
|
52
|
+
* or another upload for this app holding the storage lock. NOT retried automatically.
|
|
53
|
+
* - `rate_limited`: the user is over the route's request rate (429, default 60 a minute).
|
|
54
|
+
* {@link PluginStorageUploadError.retryAfterSeconds} carries the server's `Retry-After` when sent.
|
|
55
|
+
* NOT retried automatically.
|
|
51
56
|
* - `storage_failed`: the store refused the write (500).
|
|
52
57
|
* - `unsupported`: the active transport has no `uploadToStorage`, i.e. the host predates it.
|
|
53
58
|
* - `aborted`: the caller's signal fired.
|
|
54
59
|
* - `unknown`: anything else.
|
|
55
60
|
*/
|
|
56
|
-
type PluginStorageUploadErrorReason = "invalid_prefix" | "too_large" | "quota_exceeded" | "unauthorized" | "forbidden" | "unsupported_type" | "timeout" | "busy" | "storage_failed" | "unsupported" | "aborted" | "unknown";
|
|
61
|
+
type PluginStorageUploadErrorReason = "invalid_prefix" | "too_large" | "quota_exceeded" | "unauthorized" | "forbidden" | "unsupported_type" | "timeout" | "busy" | "rate_limited" | "storage_failed" | "unsupported" | "aborted" | "unknown";
|
|
57
62
|
/**
|
|
58
63
|
* A failed plugin-storage upload. `message` is the server's own `{ error }` text when the server
|
|
59
64
|
* answered, otherwise the client-side reason.
|
|
@@ -67,11 +72,17 @@ declare class PluginStorageUploadError extends McpToolError {
|
|
|
67
72
|
readonly reason: PluginStorageUploadErrorReason;
|
|
68
73
|
/** HTTP status from the server, when the host surfaced one. */
|
|
69
74
|
readonly status?: number;
|
|
75
|
+
/**
|
|
76
|
+
* Seconds the server asked the caller to wait (`Retry-After`), on a `rate_limited` failure
|
|
77
|
+
* when the host forwarded the header. Absent otherwise.
|
|
78
|
+
*/
|
|
79
|
+
readonly retryAfterSeconds?: number;
|
|
70
80
|
/** Structural marker for {@link isPluginStorageUploadError}. */
|
|
71
81
|
readonly isPluginStorageUploadError: true;
|
|
72
82
|
constructor(message: string, reason: PluginStorageUploadErrorReason, options?: {
|
|
73
83
|
status?: number;
|
|
74
84
|
code?: McpErrorCode;
|
|
85
|
+
retryAfterSeconds?: number;
|
|
75
86
|
});
|
|
76
87
|
}
|
|
77
88
|
/** True when `value` is a {@link PluginStorageUploadError}, including one from another bundle. */
|
|
@@ -170,6 +181,10 @@ interface UploadToStorageOptions {
|
|
|
170
181
|
* {@link PluginStorageUploadError} whose `reason` is safe to branch on and whose `message` is the
|
|
171
182
|
* server's when the server answered.
|
|
172
183
|
*
|
|
184
|
+
* An upload is NEVER retried here, on 429, 503 or anything else: it is not idempotent (a retry
|
|
185
|
+
* after a lost response could store the file twice), and a busy or rate-limited server is only
|
|
186
|
+
* made worse by it. The caller decides, using `reason` and `retryAfterSeconds`.
|
|
187
|
+
*
|
|
173
188
|
* An `ArrayBuffer` argument is transferred to the host and detached; pass a copy to keep it.
|
|
174
189
|
*/
|
|
175
190
|
declare function uploadFileToPluginStorage(transport: McpTransport, file: File | Blob | ArrayBuffer, options: UploadToStorageOptions): Promise<UploadToStorageResult>;
|
package/dist/plugin/index.d.ts
CHANGED
|
@@ -47,13 +47,18 @@ declare const PLUGIN_STORAGE_PATH_MAX_LENGTH = 128;
|
|
|
47
47
|
* - `unsupported_type`: the file's extension is not on the allow-list, or the declared type does
|
|
48
48
|
* not match it (client-side check, or a server 415).
|
|
49
49
|
* - `timeout`: the upload was too slow or missed the server's deadline (408). Retryable.
|
|
50
|
-
* - `busy`: the
|
|
50
|
+
* - `busy`: the server refused the upload for capacity (503). The message says which limit: too
|
|
51
|
+
* many uploads in progress for this user or organisation, all of the server's upload slots taken,
|
|
52
|
+
* or another upload for this app holding the storage lock. NOT retried automatically.
|
|
53
|
+
* - `rate_limited`: the user is over the route's request rate (429, default 60 a minute).
|
|
54
|
+
* {@link PluginStorageUploadError.retryAfterSeconds} carries the server's `Retry-After` when sent.
|
|
55
|
+
* NOT retried automatically.
|
|
51
56
|
* - `storage_failed`: the store refused the write (500).
|
|
52
57
|
* - `unsupported`: the active transport has no `uploadToStorage`, i.e. the host predates it.
|
|
53
58
|
* - `aborted`: the caller's signal fired.
|
|
54
59
|
* - `unknown`: anything else.
|
|
55
60
|
*/
|
|
56
|
-
type PluginStorageUploadErrorReason = "invalid_prefix" | "too_large" | "quota_exceeded" | "unauthorized" | "forbidden" | "unsupported_type" | "timeout" | "busy" | "storage_failed" | "unsupported" | "aborted" | "unknown";
|
|
61
|
+
type PluginStorageUploadErrorReason = "invalid_prefix" | "too_large" | "quota_exceeded" | "unauthorized" | "forbidden" | "unsupported_type" | "timeout" | "busy" | "rate_limited" | "storage_failed" | "unsupported" | "aborted" | "unknown";
|
|
57
62
|
/**
|
|
58
63
|
* A failed plugin-storage upload. `message` is the server's own `{ error }` text when the server
|
|
59
64
|
* answered, otherwise the client-side reason.
|
|
@@ -67,11 +72,17 @@ declare class PluginStorageUploadError extends McpToolError {
|
|
|
67
72
|
readonly reason: PluginStorageUploadErrorReason;
|
|
68
73
|
/** HTTP status from the server, when the host surfaced one. */
|
|
69
74
|
readonly status?: number;
|
|
75
|
+
/**
|
|
76
|
+
* Seconds the server asked the caller to wait (`Retry-After`), on a `rate_limited` failure
|
|
77
|
+
* when the host forwarded the header. Absent otherwise.
|
|
78
|
+
*/
|
|
79
|
+
readonly retryAfterSeconds?: number;
|
|
70
80
|
/** Structural marker for {@link isPluginStorageUploadError}. */
|
|
71
81
|
readonly isPluginStorageUploadError: true;
|
|
72
82
|
constructor(message: string, reason: PluginStorageUploadErrorReason, options?: {
|
|
73
83
|
status?: number;
|
|
74
84
|
code?: McpErrorCode;
|
|
85
|
+
retryAfterSeconds?: number;
|
|
75
86
|
});
|
|
76
87
|
}
|
|
77
88
|
/** True when `value` is a {@link PluginStorageUploadError}, including one from another bundle. */
|
|
@@ -170,6 +181,10 @@ interface UploadToStorageOptions {
|
|
|
170
181
|
* {@link PluginStorageUploadError} whose `reason` is safe to branch on and whose `message` is the
|
|
171
182
|
* server's when the server answered.
|
|
172
183
|
*
|
|
184
|
+
* An upload is NEVER retried here, on 429, 503 or anything else: it is not idempotent (a retry
|
|
185
|
+
* after a lost response could store the file twice), and a busy or rate-limited server is only
|
|
186
|
+
* made worse by it. The caller decides, using `reason` and `retryAfterSeconds`.
|
|
187
|
+
*
|
|
173
188
|
* An `ArrayBuffer` argument is transferred to the host and detached; pass a copy to keep it.
|
|
174
189
|
*/
|
|
175
190
|
declare function uploadFileToPluginStorage(transport: McpTransport, file: File | Blob | ArrayBuffer, options: UploadToStorageOptions): Promise<UploadToStorageResult>;
|
package/dist/plugin/index.js
CHANGED
|
@@ -108,6 +108,11 @@ var PluginStorageUploadError = class extends McpToolError {
|
|
|
108
108
|
reason;
|
|
109
109
|
/** HTTP status from the server, when the host surfaced one. */
|
|
110
110
|
status;
|
|
111
|
+
/**
|
|
112
|
+
* Seconds the server asked the caller to wait (`Retry-After`), on a `rate_limited` failure
|
|
113
|
+
* when the host forwarded the header. Absent otherwise.
|
|
114
|
+
*/
|
|
115
|
+
retryAfterSeconds;
|
|
111
116
|
/** Structural marker for {@link isPluginStorageUploadError}. */
|
|
112
117
|
isPluginStorageUploadError = true;
|
|
113
118
|
constructor(message, reason, options = {}) {
|
|
@@ -115,6 +120,9 @@ var PluginStorageUploadError = class extends McpToolError {
|
|
|
115
120
|
this.name = "PluginStorageUploadError";
|
|
116
121
|
this.reason = reason;
|
|
117
122
|
this.status = options.status;
|
|
123
|
+
if (options.retryAfterSeconds !== void 0) {
|
|
124
|
+
this.retryAfterSeconds = options.retryAfterSeconds;
|
|
125
|
+
}
|
|
118
126
|
}
|
|
119
127
|
};
|
|
120
128
|
function isPluginStorageUploadError(value) {
|
|
@@ -134,6 +142,8 @@ function pluginStorageUploadReasonFromStatus(status) {
|
|
|
134
142
|
return "timeout";
|
|
135
143
|
case 415:
|
|
136
144
|
return "unsupported_type";
|
|
145
|
+
case 429:
|
|
146
|
+
return "rate_limited";
|
|
137
147
|
case 503:
|
|
138
148
|
return "busy";
|
|
139
149
|
case 507:
|
|
@@ -144,6 +154,20 @@ function pluginStorageUploadReasonFromStatus(status) {
|
|
|
144
154
|
return "unknown";
|
|
145
155
|
}
|
|
146
156
|
}
|
|
157
|
+
function parsePluginStorageRetryAfter(raw, nowMs = Date.now()) {
|
|
158
|
+
if (typeof raw === "number") {
|
|
159
|
+
return Number.isFinite(raw) && raw >= 0 ? Math.ceil(raw) : void 0;
|
|
160
|
+
}
|
|
161
|
+
if (typeof raw !== "string" || raw.trim().length === 0) {
|
|
162
|
+
return void 0;
|
|
163
|
+
}
|
|
164
|
+
const text = raw.trim();
|
|
165
|
+
if (/^\d+$/.test(text)) {
|
|
166
|
+
return Number(text);
|
|
167
|
+
}
|
|
168
|
+
const at = /[A-Za-z]/.test(text) ? Date.parse(text) : Number.NaN;
|
|
169
|
+
return Number.isNaN(at) ? void 0 : Math.max(0, Math.ceil((at - nowMs) / 1e3));
|
|
170
|
+
}
|
|
147
171
|
function toPluginStorageUploadError(err) {
|
|
148
172
|
if (isPluginStorageUploadError(err)) {
|
|
149
173
|
return err;
|
|
@@ -152,7 +176,10 @@ function toPluginStorageUploadError(err) {
|
|
|
152
176
|
const candidate = err !== null && typeof err === "object" ? err : {};
|
|
153
177
|
const status = typeof candidate.status === "number" ? candidate.status : typeof candidate.statusCode === "number" ? candidate.statusCode : void 0;
|
|
154
178
|
if (status !== void 0) {
|
|
155
|
-
return new PluginStorageUploadError(message, pluginStorageUploadReasonFromStatus(status), {
|
|
179
|
+
return new PluginStorageUploadError(message, pluginStorageUploadReasonFromStatus(status), {
|
|
180
|
+
status,
|
|
181
|
+
retryAfterSeconds: parsePluginStorageRetryAfter(candidate.retryAfterSeconds)
|
|
182
|
+
});
|
|
156
183
|
}
|
|
157
184
|
if (candidate.name === "AbortError") {
|
|
158
185
|
return new PluginStorageUploadError(message, "aborted", { code: "timeout" });
|
|
@@ -328,6 +355,8 @@ function codeForReason(reason, status) {
|
|
|
328
355
|
return "forbidden";
|
|
329
356
|
case "busy":
|
|
330
357
|
return "unavailable";
|
|
358
|
+
case "rate_limited":
|
|
359
|
+
return "rate_limited";
|
|
331
360
|
case "aborted":
|
|
332
361
|
return "timeout";
|
|
333
362
|
default:
|
|
@@ -950,7 +979,7 @@ function createPortMcpTransport(port, options = {}) {
|
|
|
950
979
|
resolver.reject(new PluginStorageUploadError(
|
|
951
980
|
message,
|
|
952
981
|
status !== void 0 ? pluginStorageUploadReasonFromStatus(status) : "unknown",
|
|
953
|
-
{ status, code }
|
|
982
|
+
{ status, code, retryAfterSeconds: parsePluginStorageRetryAfter(reply.retryAfterSeconds) }
|
|
954
983
|
));
|
|
955
984
|
return;
|
|
956
985
|
}
|