@robzilla1738/agentswarm 0.2.0 → 0.5.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.
Files changed (42) hide show
  1. package/README.md +36 -5
  2. package/dist/agent.js +64 -32
  3. package/dist/cli.js +18 -4
  4. package/dist/config.js +35 -5
  5. package/dist/crawltools.js +247 -0
  6. package/dist/deepseek.js +125 -10
  7. package/dist/executor.js +771 -122
  8. package/dist/hub.js +40 -3
  9. package/dist/journal.js +61 -11
  10. package/dist/memory.js +83 -0
  11. package/dist/prompts.js +109 -16
  12. package/dist/report.js +252 -0
  13. package/dist/run.js +7 -2
  14. package/dist/searchcore.js +191 -0
  15. package/dist/state.js +57 -3
  16. package/dist/tools.js +202 -12
  17. package/dist/webtools.js +191 -60
  18. package/package.json +3 -2
  19. package/ui/out/404/index.html +1 -1
  20. package/ui/out/404.html +1 -1
  21. package/ui/out/_next/static/chunks/532-35122e93f37719b9.js +1 -0
  22. package/ui/out/_next/static/chunks/677-859e8d42add1806b.js +1 -0
  23. package/ui/out/_next/static/chunks/app/page-dc9f6744d203e76c.js +1 -0
  24. package/ui/out/_next/static/chunks/app/run/page-2420c9e4c963d9b3.js +1 -0
  25. package/ui/out/_next/static/chunks/app/settings/page-092a6bf42dfde57d.js +1 -0
  26. package/ui/out/_next/static/css/9f7bd82b8e4c762c.css +3 -0
  27. package/ui/out/fonts/PlanetKosmos.ttf +0 -0
  28. package/ui/out/index.html +1 -1
  29. package/ui/out/index.txt +3 -3
  30. package/ui/out/run/index.html +1 -1
  31. package/ui/out/run/index.txt +3 -3
  32. package/ui/out/settings/index.html +1 -1
  33. package/ui/out/settings/index.txt +3 -3
  34. package/ui/out/_next/static/chunks/383-289a866b246b41cc.js +0 -1
  35. package/ui/out/_next/static/chunks/619-ba102abea3e3d0e4.js +0 -1
  36. package/ui/out/_next/static/chunks/677-b37981ba0eca75b2.js +0 -1
  37. package/ui/out/_next/static/chunks/app/page-0c9f35bd4aa8e370.js +0 -1
  38. package/ui/out/_next/static/chunks/app/run/page-13dc41a57e34da71.js +0 -1
  39. package/ui/out/_next/static/chunks/app/settings/page-a1763be7f6de888c.js +0 -1
  40. package/ui/out/_next/static/css/82edaa7a5942f894.css +0 -3
  41. /package/ui/out/_next/static/{eiQeDU9uBHNsBj0CFkp8M → errjtBR_bKoee8ogLp8xk}/_buildManifest.js +0 -0
  42. /package/ui/out/_next/static/{eiQeDU9uBHNsBj0CFkp8M → errjtBR_bKoee8ogLp8xk}/_ssgManifest.js +0 -0
package/dist/deepseek.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CancelledError = exports.ApiError = void 0;
3
+ exports.CallGate = exports.CancelledError = exports.ApiError = void 0;
4
+ exports.gateFor = gateFor;
4
5
  exports.chat = chat;
5
6
  exports.isFatalAuthError = isFatalAuthError;
6
7
  exports.validateAuth = validateAuth;
@@ -13,10 +14,13 @@ function providerOf(cfg) {
13
14
  class ApiError extends Error {
14
15
  status;
15
16
  body;
16
- constructor(status, body) {
17
+ /** Parsed Retry-After (ms) when the server sent one with a 429. */
18
+ retryAfterMs;
19
+ constructor(status, body, retryAfterMs) {
17
20
  super(`API ${status}: ${body.slice(0, 600)}`);
18
21
  this.status = status;
19
22
  this.body = body;
23
+ this.retryAfterMs = retryAfterMs;
20
24
  }
21
25
  }
22
26
  exports.ApiError = ApiError;
@@ -66,25 +70,135 @@ function sanitizeMessages(messages, thinking) {
66
70
  });
67
71
  }
68
72
  /**
69
- * One streaming chat-completions call with retries. Streams deltas (text and
70
- * reasoning), accumulates tool calls, captures usage from the final chunk.
73
+ * Bounds concurrent streaming calls per provider endpoint so a 100-agent swarm
74
+ * doesn't turn into a 429 storm. AIMD: a 429 halves the ceiling (min 2) and
75
+ * imposes the server's Retry-After as a cool-down; sustained successes recover
76
+ * it additively back toward the configured max. Two-tier FIFO: "high" priority
77
+ * (conductor/orchestration) jumps ahead so queued workers can't starve the
78
+ * brain of the swarm.
79
+ */
80
+ class CallGate {
81
+ max;
82
+ ceiling;
83
+ active = 0;
84
+ high = [];
85
+ low = [];
86
+ successes = 0;
87
+ cooldownUntil = 0;
88
+ onState;
89
+ constructor(max) {
90
+ this.max = Math.max(1, max);
91
+ this.ceiling = this.max;
92
+ }
93
+ state() {
94
+ return { ceiling: this.ceiling, active: this.active, queued: this.high.length + this.low.length };
95
+ }
96
+ configure(max) {
97
+ this.max = Math.max(1, max);
98
+ if (this.ceiling > this.max)
99
+ this.ceiling = this.max;
100
+ this.pump();
101
+ }
102
+ async acquire(priority, signal) {
103
+ const wait = this.cooldownUntil - Date.now();
104
+ if (wait > 0)
105
+ await (0, util_1.sleep)(wait);
106
+ if (signal?.aborted)
107
+ throw new CancelledError();
108
+ if (this.active < this.ceiling) {
109
+ this.active++;
110
+ return;
111
+ }
112
+ await new Promise((resolve, reject) => {
113
+ const queue = priority === "high" ? this.high : this.low;
114
+ const entry = () => {
115
+ signal?.removeEventListener("abort", onAbort);
116
+ resolve();
117
+ };
118
+ const onAbort = () => {
119
+ const i = queue.indexOf(entry);
120
+ if (i >= 0)
121
+ queue.splice(i, 1);
122
+ reject(new CancelledError());
123
+ };
124
+ signal?.addEventListener("abort", onAbort, { once: true });
125
+ queue.push(entry);
126
+ });
127
+ }
128
+ release() {
129
+ this.active = Math.max(0, this.active - 1);
130
+ this.pump();
131
+ }
132
+ reportRateLimit(retryAfterMs) {
133
+ this.ceiling = Math.max(2, Math.floor(this.ceiling / 2));
134
+ this.successes = 0;
135
+ if (retryAfterMs && retryAfterMs > 0) {
136
+ this.cooldownUntil = Math.max(this.cooldownUntil, Date.now() + Math.min(retryAfterMs, 60_000));
137
+ }
138
+ this.onState?.(this.state());
139
+ }
140
+ reportSuccess() {
141
+ if (this.ceiling >= this.max)
142
+ return;
143
+ if (++this.successes >= 10) {
144
+ this.successes = 0;
145
+ this.ceiling++;
146
+ this.onState?.(this.state());
147
+ this.pump();
148
+ }
149
+ }
150
+ pump() {
151
+ while (this.active < this.ceiling) {
152
+ const next = this.high.shift() ?? this.low.shift();
153
+ if (!next)
154
+ break;
155
+ this.active++;
156
+ next();
157
+ }
158
+ }
159
+ }
160
+ exports.CallGate = CallGate;
161
+ const gates = new Map();
162
+ function gateFor(cfg) {
163
+ const key = cfg.baseUrl;
164
+ let g = gates.get(key);
165
+ if (!g) {
166
+ g = new CallGate(cfg.maxConcurrentCalls);
167
+ gates.set(key, g);
168
+ }
169
+ g.configure(cfg.maxConcurrentCalls);
170
+ return g;
171
+ }
172
+ /**
173
+ * One streaming chat-completions call with retries, behind the global gate.
174
+ * The retry backoff sleeps OUTSIDE the gate so a waiting call never holds a
175
+ * concurrency slot.
71
176
  */
72
177
  async function chat(cfg, o) {
178
+ const gate = gateFor(cfg);
73
179
  let lastErr;
74
180
  const attempts = 4;
75
181
  for (let i = 0; i < attempts; i++) {
182
+ await gate.acquire(o.priority ?? "normal", o.signal);
76
183
  try {
77
- return await chatOnce(cfg, o);
184
+ const res = await chatOnce(cfg, o);
185
+ gate.reportSuccess();
186
+ return res;
78
187
  }
79
188
  catch (e) {
80
189
  lastErr = e;
190
+ if (e instanceof ApiError && e.status === 429)
191
+ gate.reportRateLimit(e.retryAfterMs);
81
192
  if (!retryable(e) || i === attempts - 1)
82
193
  throw e;
83
- const backoff = [1500, 5000, 15000][i] ?? 15000;
84
- await (0, util_1.sleep)(backoff + Math.random() * 1000);
85
- if (o.signal?.aborted)
86
- throw new CancelledError();
87
194
  }
195
+ finally {
196
+ gate.release();
197
+ }
198
+ const backoff = [1500, 5000, 15000][i] ?? 15000;
199
+ await (0, util_1.sleep)(backoff + Math.random() * 1000);
200
+ if (o.signal?.aborted)
201
+ throw new CancelledError();
88
202
  }
89
203
  throw lastErr;
90
204
  }
@@ -149,7 +263,8 @@ async function chatOnce(cfg, o) {
149
263
  });
150
264
  if (!res.ok) {
151
265
  const text = await res.text().catch(() => "");
152
- throw new ApiError(res.status, text);
266
+ const ra = Number(res.headers.get("retry-after"));
267
+ throw new ApiError(res.status, text, Number.isFinite(ra) && ra >= 0 ? ra * 1000 : undefined);
153
268
  }
154
269
  if (!res.body)
155
270
  throw new ApiError(0, "empty response body");