agent-accelerator 0.5.8 → 0.6.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/README.md +26 -5
- package/examples/prompts/SYSTEM_PROMPT.md +2 -0
- package/examples/prompts/SYSTEM_PROMPT_AGENT.md +4 -0
- package/examples/prompts/SYSTEM_PROMPT_TOOLS.md +1 -0
- package/package.json +4 -1
- package/src/agent/agent.ts +374 -167
- package/src/agent/architecture.md +14 -12
- package/src/agent/config-blocks.ts +39 -12
- package/src/agent/context.ts +8 -3
- package/src/agent/delegation.ts +82 -29
- package/src/agent/loop.ts +449 -373
- package/src/agent/subagent.ts +1 -3
- package/src/agent/subagents-tool.ts +45 -7
- package/src/agent/subagents.md +3 -0
- package/src/agent/turns.ts +3 -1
- package/src/agent/worker.ts +58 -28
- package/src/agent/workers.ts +113 -20
- package/src/architecture.md +16 -15
- package/src/index.ts +34 -10
- package/src/models/architecture.md +4 -3
- package/src/models/catalog-cache.ts +6 -5
- package/src/models/catalog.ts +46 -49
- package/src/providers/architecture.md +10 -8
- package/src/providers/google.ts +150 -62
- package/src/providers/openai-compat.ts +60 -58
- package/src/providers/openai.ts +57 -39
- package/src/providers/openrouter.ts +87 -32
- package/src/providers/registry.ts +12 -26
- package/src/providers/shared.ts +89 -39
- package/src/providers.ts +56 -115
- package/src/scheduler/architecture.md +9 -8
- package/src/scheduler/scheduled-actions.md +4 -0
- package/src/scheduler/scheduler.ts +186 -60
- package/src/scheduler/store.ts +23 -10
- package/src/scheduler/time.ts +17 -3
- package/src/scheduler/tool.ts +33 -7
- package/src/session/architecture.md +7 -6
- package/src/session/journal.ts +38 -12
- package/src/session/store.ts +122 -61
- package/src/session/usage.ts +58 -9
- package/src/streaming/architecture.md +4 -3
- package/src/streaming/event-stream.ts +26 -12
- package/src/telemetry.ts +6 -2
- package/src/tools/architecture.md +8 -7
- package/src/tools/executor.ts +50 -48
- package/src/tools/schema.ts +10 -6
- package/src/tools/subagent-result.ts +6 -1
- package/src/tools/tool.ts +9 -11
- package/src/types/agent.ts +2 -21
- package/src/types/architecture.md +11 -10
- package/src/types/core.ts +1 -9
- package/src/types/errors.ts +26 -4
- package/src/types/model.ts +0 -4
- package/src/types/tool.ts +12 -2
- package/src/update-models.ts +5 -5
- package/src/utils/architecture.md +16 -15
- package/src/utils/cache.ts +1 -3
- package/src/utils/durable.ts +17 -5
- package/src/utils/env.ts +9 -7
- package/src/utils/errors.ts +50 -44
- package/src/utils/headers.ts +3 -10
- package/src/utils/media.ts +23 -8
- package/src/utils/raw-capture.ts +9 -2
- package/src/utils/retry.ts +17 -31
- package/src/utils/safe-io.ts +29 -7
- package/src/utils/serialization.ts +1 -4
- package/src/utils/session.ts +1 -2
package/src/utils/safe-io.ts
CHANGED
|
@@ -139,19 +139,31 @@ function isPrivateHostname(host: string): boolean {
|
|
|
139
139
|
// Throws RemoteFetchError for a non-http(s) URL or, unless private hosts are allowed, a private host (also by DNS result); in: fetchRemoteBytes on every hop, out: nothing or a thrown error.
|
|
140
140
|
async function assertRemoteUrlAllowed(url: URL, allowPrivateNetwork: boolean): Promise<void> {
|
|
141
141
|
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
142
|
-
throw new RemoteFetchError(
|
|
142
|
+
throw new RemoteFetchError(
|
|
143
|
+
"blocked",
|
|
144
|
+
`[Agent Accelerator] Only http(s) URLs are allowed (got ${url.protocol}).`,
|
|
145
|
+
url.href
|
|
146
|
+
);
|
|
143
147
|
}
|
|
144
148
|
if (allowPrivateNetwork) return;
|
|
145
149
|
const host = url.hostname.replace(/^\[|\]$/g, "").toLowerCase();
|
|
146
150
|
if (isPrivateHostname(host)) {
|
|
147
|
-
throw new RemoteFetchError(
|
|
151
|
+
throw new RemoteFetchError(
|
|
152
|
+
"blocked",
|
|
153
|
+
`[Agent Accelerator] Refusing to fetch private/internal host "${host}".`,
|
|
154
|
+
url.href
|
|
155
|
+
);
|
|
148
156
|
}
|
|
149
157
|
if (/^[\d.]+$/.test(host) || host.includes(":")) return; // IP literal already checked
|
|
150
158
|
try {
|
|
151
159
|
const dns = await import("node:dns");
|
|
152
160
|
const addrs = await dns.promises.lookup(host, { all: true });
|
|
153
161
|
if (addrs.some((a) => isPrivateAddress(a.address))) {
|
|
154
|
-
throw new RemoteFetchError(
|
|
162
|
+
throw new RemoteFetchError(
|
|
163
|
+
"blocked",
|
|
164
|
+
`[Agent Accelerator] Host "${host}" resolves to a private/internal address.`,
|
|
165
|
+
url.href
|
|
166
|
+
);
|
|
155
167
|
}
|
|
156
168
|
} catch (err) {
|
|
157
169
|
if (err instanceof RemoteFetchError) throw err;
|
|
@@ -169,7 +181,9 @@ async function readCapped(res: Response, maxBytes: number, url: string): Promise
|
|
|
169
181
|
);
|
|
170
182
|
const declared = Number(res.headers.get("content-length"));
|
|
171
183
|
if (Number.isFinite(declared) && declared > maxBytes) {
|
|
172
|
-
try {
|
|
184
|
+
try {
|
|
185
|
+
await res.body?.cancel();
|
|
186
|
+
} catch {}
|
|
173
187
|
throw tooLarge();
|
|
174
188
|
}
|
|
175
189
|
if (!res.body) {
|
|
@@ -185,7 +199,9 @@ async function readCapped(res: Response, maxBytes: number, url: string): Promise
|
|
|
185
199
|
if (done) break;
|
|
186
200
|
total += value.byteLength;
|
|
187
201
|
if (total > maxBytes) {
|
|
188
|
-
try {
|
|
202
|
+
try {
|
|
203
|
+
await reader.cancel();
|
|
204
|
+
} catch {}
|
|
189
205
|
throw tooLarge();
|
|
190
206
|
}
|
|
191
207
|
chunks.push(value);
|
|
@@ -227,7 +243,11 @@ export async function fetchRemoteBytes(
|
|
|
227
243
|
if ((res as { type?: string }).type === "opaqueredirect") {
|
|
228
244
|
// Browser runtimes hide the Location header: only trusted callers may follow blindly.
|
|
229
245
|
if (!allowPrivate) {
|
|
230
|
-
throw new RemoteFetchError(
|
|
246
|
+
throw new RemoteFetchError(
|
|
247
|
+
"blocked",
|
|
248
|
+
"[Agent Accelerator] Redirects cannot be validated in this runtime.",
|
|
249
|
+
current.href
|
|
250
|
+
);
|
|
231
251
|
}
|
|
232
252
|
const followed = await fetch(current.href, { signal: opts.signal });
|
|
233
253
|
return {
|
|
@@ -240,7 +260,9 @@ export async function fetchRemoteBytes(
|
|
|
240
260
|
}
|
|
241
261
|
const location = res.status >= 300 && res.status < 400 ? res.headers.get("location") : null;
|
|
242
262
|
if (location) {
|
|
243
|
-
try {
|
|
263
|
+
try {
|
|
264
|
+
await res.body?.cancel();
|
|
265
|
+
} catch {}
|
|
244
266
|
current = new URL(location, current);
|
|
245
267
|
continue;
|
|
246
268
|
}
|
|
@@ -53,10 +53,7 @@ export function toJsonSafe(value: unknown, seen = new WeakSet<object>()): unknow
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
if (value instanceof Map) {
|
|
56
|
-
return Array.from(value.entries()).map(([key, entry]) => [
|
|
57
|
-
toJsonSafe(key, seen),
|
|
58
|
-
toJsonSafe(entry, seen),
|
|
59
|
-
]);
|
|
56
|
+
return Array.from(value.entries()).map(([key, entry]) => [toJsonSafe(key, seen), toJsonSafe(entry, seen)]);
|
|
60
57
|
}
|
|
61
58
|
|
|
62
59
|
if (value instanceof Set) {
|
package/src/utils/session.ts
CHANGED
|
@@ -15,8 +15,7 @@ export function createSessionId(prefix?: string): string {
|
|
|
15
15
|
const head = prefix ? `${prefix}-` : "";
|
|
16
16
|
let id: string;
|
|
17
17
|
try {
|
|
18
|
-
const webCrypto =
|
|
19
|
-
(globalThis as any)?.crypto ?? (typeof crypto !== "undefined" ? crypto : undefined);
|
|
18
|
+
const webCrypto = (globalThis as any)?.crypto ?? (typeof crypto !== "undefined" ? crypto : undefined);
|
|
20
19
|
if (webCrypto && typeof webCrypto.randomUUID === "function") {
|
|
21
20
|
id = `${head}${webCrypto.randomUUID()}`;
|
|
22
21
|
} else {
|