You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* feat: make hardcoded plugin limits user-configurable
fs-read:
- maxReadChunkKb: per-call read limit (default 1024 KB, max 10240 KB)
- maxListResults: listDir result cap (default 1000, max 50000)
fs-write:
- maxWriteChunkKb: per-call write limit (default 2048 KB, max 10240 KB)
fetch:
- maxRedirects: HTTP redirect hops (default 5, max 20)
- maxJsonResponseBytes: fetchJSON size cap (default 1 MB, max 10 MB)
- maxTextResponseBytes: fetchText size cap (default 2 MB, max 10 MB)
All new fields follow the existing config schema pattern with sensible
defaults matching previous hardcoded values, so behaviour is unchanged
unless explicitly overridden. Hard ceilings remain as safety guards.
Signed-off-by: Simon Davies <simongdavies@users.noreply.github.com>
* feat: remove artificial ceilings from plugin config schemas
All schema 'maximum' fields removed from plugin configs. Users can now
set any value they want — the OS/hardware is the only limit, not
arbitrary numbers we picked. Defaults remain sensible and safe.
- fs-read: no ceiling on maxFileSizeKb, maxReadChunkKb, maxListResults
- fs-write: no ceiling on maxWriteSizeKb, maxWriteChunkKb, maxEntries
- fetch: no ceiling on any numeric config field (response sizes, rate
limits, timeouts, cache sizes, session budgets — all uncapped)
Removed unused MAX_SIZE_LIMIT_KB, MAX_READ_CHUNK_KB, MAX_LIST_RESULTS,
MAX_WRITE_CHUNK_KB, MAX_ENTRIES_LIMIT, MAX_REDIRECTS constants.
Updated plugin.json hints and PLUGINS.md docs to reflect configurable
(not fixed) per-call limits.
Signed-off-by: Simon Davies <simongdavies@users.noreply.github.com>
* fix: address PR #106 review feedback
Bug fixes:
- fs-read/fs-write: pass Number.MAX_SAFE_INTEGER as ceiling to
safeNumericConfig — the shared helper defaults to 10240 KB which
silently clamped maxWriteSizeKb (default 20480) and other values
back to 10 MB, defeating the 'no artificial ceilings' change
- fetch: use Buffer.byteLength(body, 'utf8') instead of body.length
for maxJsonResponseBytes and maxTextResponseBytes guards — body.length
counts UTF-16 code units which undercounts for non-ASCII content
New tests (14 tests added):
- fs-read: maxReadChunkKb enforcement, maxListResults truncation,
maxFileSizeKb above old 10 MB ceiling
- fs-write: maxWriteChunkKb enforcement for text and binary writes,
maxWriteSizeKb above old 50 MB ceiling
- fetch: config acceptance for maxRedirects, maxJsonResponseBytes,
maxTextResponseBytes, maxDataReceivedKb, and uncapped rate limits
Signed-off-by: Simon Davies <simongdavies@users.noreply.github.com>
---------
Signed-off-by: Simon Davies <simongdavies@users.noreply.github.com>
Copy file name to clipboardExpand all lines: plugins/fetch/index.ts
+87-54Lines changed: 87 additions & 54 deletions
Original file line number
Diff line number
Diff line change
@@ -95,76 +95,66 @@ export const SCHEMA = {
95
95
},
96
96
connectTimeoutMs: {
97
97
type: "number"asconst,
98
-
description: "TCP+TLS connect timeout in milliseconds (max 10000)",
98
+
description: "TCP+TLS connect timeout in milliseconds",
99
99
default: 5000,
100
100
minimum: 1000,
101
-
maximum: 10000,
102
101
},
103
102
readTimeoutMs: {
104
103
type: "number"asconst,
105
-
description: "Read timeout in milliseconds (max 30000)",
104
+
description: "Read timeout in milliseconds",
106
105
default: 10000,
107
106
minimum: 1000,
108
-
maximum: 30000,
109
107
},
110
108
maxResponseSizeKb: {
111
109
type: "number"asconst,
112
110
description:
113
-
"Maximum total response body size in KB (max 8192). Responses larger than this are rejected.",
111
+
"Maximum total response body size in KB. Responses larger than this are rejected.",
114
112
default: 1024,
115
113
minimum: 1,
116
-
maximum: 8192,
117
114
},
118
115
readSizeKb: {
119
116
type: "number"asconst,
120
117
description:
121
-
"Maximum body size returned per read() call in KB (max 256). Must be smaller than the sandbox output buffer.",
118
+
"Maximum body size returned per read() call in KB. Must be smaller than the sandbox output buffer.",
122
119
default: 48,
123
120
minimum: 8,
124
-
maximum: 256,
125
121
},
126
122
responseCacheTtlSeconds: {
127
123
type: "number"asconst,
128
124
description:
129
-
"How long response bodies stay cached on the host before expiring (seconds, max 600)",
125
+
"How long response bodies stay cached on the host before expiring (seconds)",
130
126
default: 300,
131
127
minimum: 30,
132
-
maximum: 600,
133
128
},
134
129
maxRequestBodySizeKb: {
135
130
type: "number"asconst,
136
-
description: "Maximum POST request body size in KB (max 64)",
131
+
description: "Maximum POST request body size in KB",
137
132
default: 4,
138
133
minimum: 1,
139
-
maximum: 64,
140
134
},
141
135
maxRequestsPerMinute: {
142
136
type: "number"asconst,
143
137
description: "Maximum fetch calls per minute (sliding window)",
144
138
default: 30,
145
139
minimum: 1,
146
-
maximum: 60,
147
140
},
148
141
maxRequestsPerHour: {
149
142
type: "number"asconst,
150
143
description: "Maximum fetch calls per hour (session-scoped)",
151
144
default: 100,
152
145
minimum: 1,
153
-
maximum: 500,
154
146
},
155
147
maxDomainsPerSession: {
156
148
type: "number"asconst,
157
149
description: "Maximum unique domains per session",
158
150
default: 5,
159
151
minimum: 1,
160
-
maximum: 20,
161
152
},
162
153
maxDataReceivedKb: {
163
154
type: "number"asconst,
164
155
description: "Maximum total response data per session in KB",
165
156
default: 2048,
166
157
minimum: 1,
167
-
maximum: 16384,
168
158
},
169
159
returnXRequestId: {
170
160
type: "boolean"asconst,
@@ -175,18 +165,16 @@ export const SCHEMA = {
175
165
conditionalCacheMaxEntries: {
176
166
type: "number"asconst,
177
167
description:
178
-
"Maximum number of URLs cached for conditional requests (ETag/Last-Modified). 0 effectively disables caching (min 1).",
168
+
"Maximum number of URLs cached for conditional requests (ETag/Last-Modified).",
179
169
default: 20,
180
170
minimum: 1,
181
-
maximum: 100,
182
171
},
183
172
conditionalCacheTtlSeconds: {
184
173
type: "number"asconst,
185
174
description:
186
175
"How long conditional-cache entries remain valid (seconds). After this, the next GET sends a normal request without conditional headers.",
187
176
default: 600,
188
177
minimum: 60,
189
-
maximum: 3600,
190
178
},
191
179
autoRetryOn429: {
192
180
type: "boolean"asconst,
@@ -200,31 +188,48 @@ export const SCHEMA = {
200
188
"Maximum seconds to wait for a single 429 retry. If server asks for longer, returns error instead of waiting.",
201
189
default: 30,
202
190
minimum: 1,
203
-
maximum: 120,
204
191
},
205
192
autoRetryMaxAttempts: {
206
193
type: "number"asconst,
207
194
description:
208
195
"Maximum number of retry attempts on 429 before giving up and returning the error.",
209
196
default: 3,
210
197
minimum: 1,
211
-
maximum: 10,
212
198
},
213
199
maxParallelFetches: {
214
200
type: "number"asconst,
215
201
description:
216
202
"Maximum concurrent requests for batch operations like fetchBinaryBatch. Higher values speed up bulk downloads but may trigger server rate limits. Default 1 (serial).",
217
203
default: 1,
218
204
minimum: 1,
219
-
maximum: 10,
220
205
},
221
206
diskCacheMaxMb: {
222
207
type: "number"asconst,
223
208
description:
224
209
"Maximum disk cache size in MB for anonymous HTTP responses. Cached in $HOME/.hyperagent/fetch-cache with LFU eviction. Set to 0 to disable.",
225
210
default: 100,
226
211
minimum: 0,
227
-
maximum: 1000,
212
+
},
213
+
maxRedirects: {
214
+
type: "number"asconst,
215
+
description:
216
+
"Maximum number of HTTP redirects to follow. Each hop is re-validated against the domain allowlist and SSRF checks.",
217
+
default: 5,
218
+
minimum: 0,
219
+
},
220
+
maxJsonResponseBytes: {
221
+
type: "number"asconst,
222
+
description:
223
+
"Maximum response size in bytes for fetchJSON convenience method. Larger responses should use get() + read() streaming.",
224
+
default: 1048576,
225
+
minimum: 1024,
226
+
},
227
+
maxTextResponseBytes: {
228
+
type: "number"asconst,
229
+
description:
230
+
"Maximum response size in bytes for fetchText convenience method. Larger responses should use get() + read() streaming.",
0 commit comments