@bolloon/bolloon-agent 0.3.29 → 0.3.30

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/llm/pi-ai.js CHANGED
@@ -282,15 +282,34 @@ export class PiAIModel {
282
282
  const _t0 = Date.now();
283
283
  for (let attempt = 0; attempt < 3; attempt++) {
284
284
  const _tFetch = Date.now();
285
- const response = await fetch(`${this.getBaseUrl()}/chat/completions`, {
286
- method: 'POST',
287
- headers: {
288
- 'Content-Type': 'application/json',
289
- 'Authorization': `Bearer ${apiKey}`
290
- },
291
- body: JSON.stringify(requestBody),
292
- signal: this.combinedSignal(signal),
293
- });
285
+ let response;
286
+ try {
287
+ response = await fetch(`${this.getBaseUrl()}/chat/completions`, {
288
+ method: 'POST',
289
+ headers: {
290
+ 'Content-Type': 'application/json',
291
+ 'Authorization': `Bearer ${apiKey}`
292
+ },
293
+ body: JSON.stringify(requestBody),
294
+ signal: this.combinedSignal(signal),
295
+ });
296
+ }
297
+ catch (err) {
298
+ // 2026-08-04: 网络层瞬时错误 (undici "terminated" / ECONNRESET / socket hang up / fetch failed 等)
299
+ // 退避重试最多 2 次 — 之前直接抛给 chat() 变成 "[AI 服务调用失败] terminated" 打断 agent 流程.
300
+ // abort (用户主动 / 120s 超时) 不重试, 原样抛出.
301
+ if (err?.name === 'AbortError' || signal?.aborted)
302
+ throw err;
303
+ const netMsg = String(err?.message || err?.cause?.message || '');
304
+ const isNetworkErr = /terminated|ECONNRESET|socket hang up|fetch failed|network|ETIMEDOUT|ECONNREFUSED|UND_ERR/i.test(netMsg);
305
+ if (attempt < 2 && isNetworkErr) {
306
+ const backoff = 1500 * (attempt + 1);
307
+ console.warn(`[pi-ai] 网络错误 attempt ${attempt + 1}/3: ${netMsg.slice(0, 120)}, 退避 ${backoff}ms 重试`);
308
+ await new Promise(resolve => setTimeout(resolve, backoff));
309
+ continue;
310
+ }
311
+ throw err;
312
+ }
294
313
  const _tResp = Date.now();
295
314
  if (!response.ok) {
296
315
  const errBody = await response.text().catch(() => '(no body)');
@@ -202,23 +202,7 @@ export function checkOutput(output) {
202
202
  };
203
203
  }
204
204
  // ============================================================
205
- // Gate 7: 链式调用限制 (单轮最多 5 tool, agent 循环)
206
- // ============================================================
207
- const MAX_TOOL_CALLS_PER_TURN = 5;
208
- export function checkChain(ctx) {
209
- const count = ctx.toolCallCountInTurn ?? 0;
210
- if (count >= MAX_TOOL_CALLS_PER_TURN) {
211
- return {
212
- gate: 'chain',
213
- allowed: false,
214
- reason: `单轮已调 ${count} 个 tool (上限 ${MAX_TOOL_CALLS_PER_TURN})`,
215
- evidence: `当前轮 tool 调用次数: ${count}`,
216
- };
217
- }
218
- return { gate: 'chain', allowed: true };
219
- }
220
- // ============================================================
221
- // Gate 8: 黑名单 (复用 PreToolUse hook 已有 6 条规则, 重新实现于此)
205
+ // Gate 7: 黑名单 (复用 PreToolUse hook 已有 6 条规则, 重新实现于此)
222
206
  // ============================================================
223
207
  const DANGEROUS_CMD_PATTERNS = [
224
208
  { re: /\brm\s+(-[a-z]*f[a-z]*\s+)?-[a-z]*r[a-z]*\s+\//, reason: '禁止递归删除根目录' },
@@ -245,7 +229,7 @@ const TOOL_GATES = [
245
229
  checkChannel,
246
230
  checkRate,
247
231
  checkInject,
248
- checkChain, // 链式限制前置 (chain)
232
+ // 2026-08-04: 移除 checkChain 单轮 5 工具上限会打断 agent 长流程 (MCP 多步测试被反复拦), 用户要求去掉
249
233
  checkBlacklist,
250
234
  // checkOutput 不在 tool.execute 前
251
235
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bolloon/bolloon-agent",
3
- "version": "0.3.29",
3
+ "version": "0.3.30",
4
4
  "type": "module",
5
5
  "description": "P2P AI Document Agent - 全局安装后执行 `bolloon` 启动产品",
6
6
  "main": "dist/cli-entry.js",