@ai-setting/roy-agent-core 1.7.62 → 1.7.64

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 (125) hide show
  1. package/dist/config/index.js +9 -9
  2. package/dist/env/agent/agent-component.d.ts +33 -0
  3. package/dist/env/agent/agent-component.js +16 -15
  4. package/dist/env/agent/index.js +16 -15
  5. package/dist/env/agent/types.d.ts +17 -0
  6. package/dist/env/commands/index.js +9 -9
  7. package/dist/env/context/index.js +5 -5
  8. package/dist/env/debug/index.js +9 -9
  9. package/dist/env/error-reply.d.ts +53 -1
  10. package/dist/env/error-reply.js +10 -3
  11. package/dist/env/event-source/bounty-im-handler.d.ts +1 -1
  12. package/dist/env/event-source/cli-command-handler.js +3 -3
  13. package/dist/env/event-source/event-source-handlers.js +22 -21
  14. package/dist/env/event-source/event-store.js +4 -4
  15. package/dist/env/event-source/index.js +23 -22
  16. package/dist/env/hook/index.js +7 -7
  17. package/dist/env/index.js +49 -48
  18. package/dist/env/llm/adapter-pi-ai.d.ts +47 -0
  19. package/dist/env/llm/index.js +11 -10
  20. package/dist/env/llm/model-fallback.d.ts +54 -0
  21. package/dist/env/llm/redact.d.ts +39 -0
  22. package/dist/env/llm/types.d.ts +13 -0
  23. package/dist/env/log-trace/index.js +9 -9
  24. package/dist/env/log-trace/logger.js +2 -2
  25. package/dist/env/mcp/index.js +10 -10
  26. package/dist/env/mcp/tool/index.js +3 -3
  27. package/dist/env/memory/index.js +10 -10
  28. package/dist/env/memory/plugin/index.js +3 -3
  29. package/dist/env/plugin/index.js +9 -9
  30. package/dist/env/prompt/index.js +9 -9
  31. package/dist/env/session/index.js +13 -12
  32. package/dist/env/session/storage/index.js +7 -6
  33. package/dist/env/skill/index.js +9 -9
  34. package/dist/env/task/delegate/delegate-tool.d.ts +27 -1
  35. package/dist/env/task/delegate/delegate-tool.js +10 -10
  36. package/dist/env/task/delegate/index.js +10 -10
  37. package/dist/env/task/index.js +16 -16
  38. package/dist/env/task/mcp/index.js +5 -5
  39. package/dist/env/task/plugins/index.js +12 -12
  40. package/dist/env/task/plugins/lark-card-patch-notifier.js +4 -4
  41. package/dist/env/task/storage/index.js +5 -5
  42. package/dist/env/task/tools/index.js +5 -5
  43. package/dist/env/tool/built-in/index.js +5 -5
  44. package/dist/env/tool/index.js +12 -12
  45. package/dist/env/tool/types.d.ts +13 -0
  46. package/dist/env/workflow/engine/index.js +14 -14
  47. package/dist/env/workflow/hooks/index.js +9 -9
  48. package/dist/env/workflow/index.js +25 -24
  49. package/dist/env/workflow/nodes/index.js +4 -4
  50. package/dist/env/workflow/plugins/index.js +10 -10
  51. package/dist/env/workflow/service/index.js +4 -4
  52. package/dist/env/workflow/storage/index.js +5 -5
  53. package/dist/env/workflow/tools/index.js +17 -16
  54. package/dist/env/workflow/utils/index.js +6 -6
  55. package/dist/index.js +60 -59
  56. package/dist/shared/@ai-setting/{roy-agent-core-sj4y3wdm.js → roy-agent-core-002g6nfk.js} +3 -3
  57. package/dist/shared/@ai-setting/{roy-agent-core-06jakebr.js → roy-agent-core-07fvy74y.js} +2 -2
  58. package/dist/shared/@ai-setting/{roy-agent-core-fr296a53.js → roy-agent-core-0cb6w0k7.js} +5 -5
  59. package/dist/shared/@ai-setting/{roy-agent-core-cxpgd415.js → roy-agent-core-0ys85x46.js} +6 -6
  60. package/dist/shared/@ai-setting/{roy-agent-core-6wxww10t.js → roy-agent-core-12n08pg5.js} +2 -2
  61. package/dist/shared/@ai-setting/{roy-agent-core-nmn853z0.js → roy-agent-core-1h5bbqcg.js} +11 -11
  62. package/dist/shared/@ai-setting/{roy-agent-core-h3fwjbhp.js → roy-agent-core-37tj4y6a.js} +14 -14
  63. package/dist/shared/@ai-setting/{roy-agent-core-gjsvehfs.js → roy-agent-core-3wrveh5p.js} +2 -2
  64. package/dist/shared/@ai-setting/{roy-agent-core-9qgrc9dy.js → roy-agent-core-40rv283c.js} +56 -16
  65. package/dist/shared/@ai-setting/{roy-agent-core-kvq4a4p6.js → roy-agent-core-5pr4zp88.js} +2 -2
  66. package/dist/shared/@ai-setting/{roy-agent-core-qmqe8ds3.js → roy-agent-core-6j02sbee.js} +3 -3
  67. package/dist/shared/@ai-setting/{roy-agent-core-hfyxv2kx.js → roy-agent-core-7cbpmk4q.js} +2 -2
  68. package/dist/shared/@ai-setting/{roy-agent-core-6awgfh3x.js → roy-agent-core-7f7t9wwp.js} +1 -1
  69. package/dist/shared/@ai-setting/roy-agent-core-83bewqx8.js +10 -0
  70. package/dist/shared/@ai-setting/{roy-agent-core-jnszp0jq.js → roy-agent-core-85xyctnb.js} +7 -2
  71. package/dist/shared/@ai-setting/{roy-agent-core-2pma868e.js → roy-agent-core-87942bw4.js} +5 -5
  72. package/dist/shared/@ai-setting/{roy-agent-core-ja4sr63d.js → roy-agent-core-8cx7cfdg.js} +7 -7
  73. package/dist/shared/@ai-setting/{roy-agent-core-th92f833.js → roy-agent-core-9bs6xrav.js} +2 -2
  74. package/dist/shared/@ai-setting/{roy-agent-core-48h4zh60.js → roy-agent-core-9bshyqjn.js} +4 -4
  75. package/dist/shared/@ai-setting/{roy-agent-core-9nvyffxg.js → roy-agent-core-add1zqsh.js} +118 -8
  76. package/dist/shared/@ai-setting/{roy-agent-core-7tce05jt.js → roy-agent-core-ax9e9szb.js} +1 -1
  77. package/dist/shared/@ai-setting/{roy-agent-core-8xv4qzx7.js → roy-agent-core-br9cdm8d.js} +1 -1
  78. package/dist/shared/@ai-setting/{roy-agent-core-zjgckbdd.js → roy-agent-core-c2gbt68e.js} +2 -2
  79. package/dist/shared/@ai-setting/{roy-agent-core-v7mwj8eq.js → roy-agent-core-cpcd24n2.js} +2 -2
  80. package/dist/shared/@ai-setting/{roy-agent-core-hczj1ryh.js → roy-agent-core-dc9zq75z.js} +5 -5
  81. package/dist/shared/@ai-setting/{roy-agent-core-zy8vkbnk.js → roy-agent-core-dvtg4sn0.js} +1 -1
  82. package/dist/shared/@ai-setting/{roy-agent-core-cqpd41gf.js → roy-agent-core-e4hehcdr.js} +8 -8
  83. package/dist/shared/@ai-setting/{roy-agent-core-hwkc0bg2.js → roy-agent-core-efkjyh69.js} +1 -1
  84. package/dist/shared/@ai-setting/{roy-agent-core-dfqhc9ey.js → roy-agent-core-es203w7p.js} +2 -2
  85. package/dist/shared/@ai-setting/{roy-agent-core-w2ev3z5q.js → roy-agent-core-es467wsz.js} +6 -6
  86. package/dist/shared/@ai-setting/{roy-agent-core-p8rf4z89.js → roy-agent-core-f77k3gqt.js} +1 -1
  87. package/dist/shared/@ai-setting/{roy-agent-core-jw63js86.js → roy-agent-core-fttgm52a.js} +1 -1
  88. package/dist/shared/@ai-setting/{roy-agent-core-32ck9rqt.js → roy-agent-core-g8htfwxj.js} +2 -2
  89. package/dist/shared/@ai-setting/{roy-agent-core-5mrynf9g.js → roy-agent-core-gxzxq1sf.js} +1 -1
  90. package/dist/shared/@ai-setting/{roy-agent-core-fqandv0a.js → roy-agent-core-hjejpcg5.js} +29 -19
  91. package/dist/shared/@ai-setting/{roy-agent-core-2veqhrxa.js → roy-agent-core-hy3zn2q2.js} +3 -3
  92. package/dist/shared/@ai-setting/{roy-agent-core-wzp4tbsn.js → roy-agent-core-jvv2h3d6.js} +1 -1
  93. package/dist/shared/@ai-setting/{roy-agent-core-prnry2mw.js → roy-agent-core-jz8dsypm.js} +3 -3
  94. package/dist/shared/@ai-setting/{roy-agent-core-x1d6edkh.js → roy-agent-core-kmbct9yg.js} +1 -1
  95. package/dist/shared/@ai-setting/{roy-agent-core-gc6wcd7z.js → roy-agent-core-mcy5apay.js} +1 -1
  96. package/dist/shared/@ai-setting/{roy-agent-core-p6a4v4fq.js → roy-agent-core-mds8tqd0.js} +1 -1
  97. package/dist/shared/@ai-setting/{roy-agent-core-bpvz1dqr.js → roy-agent-core-mw2cen6s.js} +8 -8
  98. package/dist/shared/@ai-setting/{roy-agent-core-a08dpf71.js → roy-agent-core-na18zwj0.js} +1 -1
  99. package/dist/shared/@ai-setting/{roy-agent-core-2hkyp51n.js → roy-agent-core-nm4xbs1d.js} +1 -1
  100. package/dist/shared/@ai-setting/roy-agent-core-ntn32q7j.js +72 -0
  101. package/dist/shared/@ai-setting/{roy-agent-core-79gyka2q.js → roy-agent-core-nwbfepba.js} +2 -2
  102. package/dist/shared/@ai-setting/{roy-agent-core-gtdtzbs7.js → roy-agent-core-pgvcf91v.js} +2 -2
  103. package/dist/shared/@ai-setting/{roy-agent-core-084zthqx.js → roy-agent-core-q96qynhb.js} +1 -1
  104. package/dist/shared/@ai-setting/{roy-agent-core-386wa4wy.js → roy-agent-core-qq96p0tj.js} +1 -1
  105. package/dist/shared/@ai-setting/{roy-agent-core-33hn1beg.js → roy-agent-core-qqaak24r.js} +1 -1
  106. package/dist/shared/@ai-setting/{roy-agent-core-vwzan9v0.js → roy-agent-core-r5wt1h3c.js} +2 -2
  107. package/dist/shared/@ai-setting/{roy-agent-core-vvb4cyyy.js → roy-agent-core-rjzdj0xb.js} +11 -6
  108. package/dist/shared/@ai-setting/{roy-agent-core-ye4bfzqg.js → roy-agent-core-ry2eztft.js} +11 -11
  109. package/dist/shared/@ai-setting/{roy-agent-core-c57278kx.js → roy-agent-core-sjr1kmfz.js} +1 -1
  110. package/dist/shared/@ai-setting/{roy-agent-core-anb53t3v.js → roy-agent-core-tm1mxttk.js} +4 -4
  111. package/dist/shared/@ai-setting/{roy-agent-core-p37kh0kt.js → roy-agent-core-v0hf14bj.js} +1 -1
  112. package/dist/shared/@ai-setting/{roy-agent-core-c4t4y18j.js → roy-agent-core-v6vr6za7.js} +5 -5
  113. package/dist/shared/@ai-setting/{roy-agent-core-w2h6xt6k.js → roy-agent-core-vd9zak15.js} +4 -4
  114. package/dist/shared/@ai-setting/{roy-agent-core-gz2jnaan.js → roy-agent-core-vncwfzw5.js} +8 -8
  115. package/dist/shared/@ai-setting/{roy-agent-core-c8xvy6hj.js → roy-agent-core-w07ymg29.js} +4 -4
  116. package/dist/shared/@ai-setting/{roy-agent-core-mbwaxqs0.js → roy-agent-core-xcp8vwax.js} +4 -4
  117. package/dist/shared/@ai-setting/{roy-agent-core-5bj0xfjk.js → roy-agent-core-xhrrgfdy.js} +324 -43
  118. package/dist/shared/@ai-setting/{roy-agent-core-mkpsz128.js → roy-agent-core-xvt7kf7p.js} +5 -5
  119. package/dist/shared/@ai-setting/{roy-agent-core-as0dd70m.js → roy-agent-core-xw4wsj38.js} +2 -2
  120. package/dist/shared/@ai-setting/{roy-agent-core-kmvw6b4v.js → roy-agent-core-yr1mryb8.js} +1 -1
  121. package/dist/shared/@ai-setting/{roy-agent-core-m3w3ytxt.js → roy-agent-core-zk2jg0v7.js} +2 -2
  122. package/dist/shared/@ai-setting/{roy-agent-core-mrrv80jy.js → roy-agent-core-zxz5fkwj.js} +1 -1
  123. package/dist/utils/temp-file-manager/index.js +3 -3
  124. package/package.json +1 -1
  125. package/dist/shared/@ai-setting/roy-agent-core-a6cz4d23.js +0 -10
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  isToolUnavailableError,
3
3
  truncateOutputInline
4
- } from "./roy-agent-core-w2ev3z5q.js";
4
+ } from "./roy-agent-core-es467wsz.js";
5
5
  import {
6
6
  AgentRegistry
7
- } from "./roy-agent-core-06jakebr.js";
7
+ } from "./roy-agent-core-07fvy74y.js";
8
8
  import {
9
9
  enqueueToAddFakeUserMessage
10
- } from "./roy-agent-core-p8rf4z89.js";
10
+ } from "./roy-agent-core-f77k3gqt.js";
11
11
  import {
12
12
  SessionMessageConverter
13
- } from "./roy-agent-core-x1d6edkh.js";
13
+ } from "./roy-agent-core-kmbct9yg.js";
14
14
  import {
15
15
  parseToolArgsStrict,
16
16
  safeParseToolArgs,
17
17
  withTimeout
18
- } from "./roy-agent-core-9qgrc9dy.js";
18
+ } from "./roy-agent-core-40rv283c.js";
19
19
  import {
20
20
  getCurrentBgTaskId
21
21
  } from "./roy-agent-core-c1v263jn.js";
@@ -31,20 +31,20 @@ import {
31
31
  } from "./roy-agent-core-7hh0brvs.js";
32
32
  import {
33
33
  BaseComponent
34
- } from "./roy-agent-core-gtdtzbs7.js";
34
+ } from "./roy-agent-core-pgvcf91v.js";
35
35
  import {
36
36
  globalHookManager,
37
37
  init_global_hook_manager
38
- } from "./roy-agent-core-v7mwj8eq.js";
38
+ } from "./roy-agent-core-cpcd24n2.js";
39
39
  import {
40
40
  init_context
41
- } from "./roy-agent-core-33hn1beg.js";
41
+ } from "./roy-agent-core-qqaak24r.js";
42
42
  import {
43
43
  getCurrentTaskId,
44
44
  getEnvContext,
45
45
  resolveEnvParentTaskId,
46
46
  runWithEnvContextAsync
47
- } from "./roy-agent-core-hfyxv2kx.js";
47
+ } from "./roy-agent-core-7cbpmk4q.js";
48
48
  import {
49
49
  TracedAs,
50
50
  agentRunParamFilter,
@@ -56,11 +56,11 @@ import {
56
56
  recordSessionMessagesParamFilter,
57
57
  toolExecParamFilter,
58
58
  toolExecResultFilter
59
- } from "./roy-agent-core-386wa4wy.js";
59
+ } from "./roy-agent-core-qq96p0tj.js";
60
60
  import {
61
61
  createLogger,
62
62
  init_logger
63
- } from "./roy-agent-core-6awgfh3x.js";
63
+ } from "./roy-agent-core-7f7t9wwp.js";
64
64
  import {
65
65
  __legacyDecorateClassTS,
66
66
  __require
@@ -197,6 +197,201 @@ var AGENT_CONFIG_REGISTRATION = {
197
197
  // src/env/agent/agent-component.ts
198
198
  init_decorator();
199
199
  init_trace_filters();
200
+
201
+ // src/env/llm/model-fallback.ts
202
+ var NON_FALLBACKABLE_STATUS = new Set([400, 401, 403]);
203
+ var MODEL_UNAVAILABLE_PATTERNS = [
204
+ /model(?:\s+id|\s+name)?\s+(?:is\s+)?(?:unavailable|not\s+available)/i,
205
+ /model(?:\s+id|\s+name)?\s+(?:is\s+)?(?:not\s+found|does\s+not\s+exist|not\s+supported|deprecated|disabled|invalid|unknown)/i,
206
+ /\b(?:unknown|unsupported|nonexistent)\s+model\b/i,
207
+ /model[_\s-]?not[_\s-]?found/i,
208
+ /no\s+such\s+model/i,
209
+ /模型(?:不存在|不可用|未找到|不支持|已下线)/
210
+ ];
211
+ var CREDIT_PATTERNS = [
212
+ /credit balance/i,
213
+ /balance (?:is )?too? ?low/i,
214
+ /insufficient (?:balance|credits?|funds?)/i,
215
+ /payment required/i,
216
+ /\b402\b/,
217
+ /充值|欠费/
218
+ ];
219
+ var INTRINSIC_BLOCKERS = [
220
+ /abort(?:ed|error)?/i,
221
+ /operation was (?:aborted|cancelled)/i,
222
+ /context threshold exceeded/i,
223
+ /context window (?:exceeded|overflow)/i
224
+ ];
225
+ var QUOTA_PATTERNS = [
226
+ /insufficient[_ ]quota/i,
227
+ /exceeded your current quota/i,
228
+ /quota (?:exceeded|exhausted)/i,
229
+ /rate[ _-]?limit/i,
230
+ /\b429\b/,
231
+ /too many requests/i,
232
+ /billing/i,
233
+ /insufficient balance/i,
234
+ /余额不足/i,
235
+ /额度(?:不足|耗尽|用尽|超限)/,
236
+ /配额(?:不足|耗尽|用尽)/
237
+ ];
238
+ var SERVER_ERROR_PATTERNS = [
239
+ /(?:http|status|code|error)\D{0,12}5\d{2}\b/i,
240
+ /\b5\d{2}\s+(?:internal|bad\s+gateway|service\s+unavailable|gateway\s+timeout|server\s+error)/i,
241
+ /internal server error/i,
242
+ /bad gateway/i,
243
+ /service unavailable/i,
244
+ /gateway timeout/i,
245
+ /overloaded/i
246
+ ];
247
+ var TIMEOUT_PATTERNS = [
248
+ /timed?[\s_-]?out/i,
249
+ /timeout/i,
250
+ /etimedout/i,
251
+ /econnreset/i,
252
+ /econnrefused/i,
253
+ /socket hang up/i,
254
+ /network (?:error|failure)/i,
255
+ /fetch failed/i
256
+ ];
257
+ var RETRY_EXHAUSTED_PATTERNS = [
258
+ /retry(?:ing)? (?:failed|exhausted)/i,
259
+ /retries exhausted/i,
260
+ /max(?:imum)? ?retries/i,
261
+ /too many retries/i,
262
+ /\bretryerror\b/i,
263
+ /all retries? failed/i,
264
+ /failed after \d+ attempts(?:\. last error| with non-retryable error)/i,
265
+ /ai_?retryerror/i
266
+ ];
267
+ var GATEWAY_NO_DEPLOYMENT_PATTERNS = [
268
+ /no deployments? available/i,
269
+ /try again in \d+ seconds?/i,
270
+ /cooldown_list/i,
271
+ /pre-call-checks/i
272
+ ];
273
+ var GATEWAY_LB_STRONG_PATTERNS = [
274
+ /no deployments? available/i,
275
+ /cooldown_list/i,
276
+ /pre-call-checks/i
277
+ ];
278
+ var HARD_BLOCKERS = [
279
+ /\b401\b/,
280
+ /unauthorized/i,
281
+ /\b403\b/,
282
+ /forbidden/i,
283
+ /invalid[ _-]?api[ _-]?key/i,
284
+ /authentication (?:failed|error)/i,
285
+ /\b400\b/,
286
+ /bad request/i,
287
+ /abort(?:ed|error)?/i,
288
+ /operation was (?:aborted|cancelled)/i,
289
+ /context threshold exceeded/i,
290
+ /context window (?:exceeded|overflow)/i
291
+ ];
292
+ function extractStatusCode(error) {
293
+ if (!error || typeof error !== "object")
294
+ return;
295
+ const candidate = error;
296
+ const cause = candidate.cause ?? undefined;
297
+ const raw = candidate.statusCode ?? candidate.status ?? candidate.response?.status ?? cause?.statusCode ?? cause?.status;
298
+ const num = typeof raw === "number" ? raw : Number(raw);
299
+ return Number.isFinite(num) && num > 0 ? num : undefined;
300
+ }
301
+ var TEXT_KEYS = [
302
+ "message",
303
+ "errorMessage",
304
+ "reason",
305
+ "detail",
306
+ "body",
307
+ "responseBody",
308
+ "error",
309
+ "data",
310
+ "lastError"
311
+ ];
312
+ function collectErrorText(error) {
313
+ const parts = [];
314
+ const pushFromObject = (obj) => {
315
+ for (const key of TEXT_KEYS) {
316
+ const value = obj[key];
317
+ if (typeof value === "string")
318
+ parts.push(value);
319
+ }
320
+ };
321
+ if (typeof error === "string") {
322
+ parts.push(error);
323
+ } else if (error instanceof Error) {
324
+ parts.push(error.message);
325
+ parts.push(error.name);
326
+ const cause = error.cause;
327
+ if (cause instanceof Error) {
328
+ parts.push(cause.message);
329
+ parts.push(cause.name);
330
+ } else if (typeof cause === "string") {
331
+ parts.push(cause);
332
+ } else if (cause && typeof cause === "object") {
333
+ pushFromObject(cause);
334
+ }
335
+ } else if (error && typeof error === "object") {
336
+ pushFromObject(error);
337
+ }
338
+ return parts.filter(Boolean).join(" | ");
339
+ }
340
+ function isFallbackEligibleError(error, hasFallback = true) {
341
+ if (!hasFallback)
342
+ return false;
343
+ if (error === undefined || error === null)
344
+ return false;
345
+ const text = collectErrorText(error);
346
+ const status = extractStatusCode(error);
347
+ const timedOut = TIMEOUT_PATTERNS.some((re) => re.test(text));
348
+ if (timedOut)
349
+ return true;
350
+ if (INTRINSIC_BLOCKERS.some((re) => re.test(text)))
351
+ return false;
352
+ if (MODEL_UNAVAILABLE_PATTERNS.some((re) => re.test(text)))
353
+ return true;
354
+ if (CREDIT_PATTERNS.some((re) => re.test(text)))
355
+ return true;
356
+ if (GATEWAY_LB_STRONG_PATTERNS.some((re) => re.test(text)))
357
+ return true;
358
+ if (HARD_BLOCKERS.some((re) => re.test(text)))
359
+ return false;
360
+ if (status !== undefined && NON_FALLBACKABLE_STATUS.has(status))
361
+ return false;
362
+ if (status !== undefined) {
363
+ if (status === 404 || status === 408 || status === 429 || status >= 500)
364
+ return true;
365
+ }
366
+ if (/(?:^|[^/\w])404(?!\d)/.test(text))
367
+ return true;
368
+ if (QUOTA_PATTERNS.some((re) => re.test(text)))
369
+ return true;
370
+ if (SERVER_ERROR_PATTERNS.some((re) => re.test(text)))
371
+ return true;
372
+ if (RETRY_EXHAUSTED_PATTERNS.some((re) => re.test(text)))
373
+ return true;
374
+ if (GATEWAY_NO_DEPLOYMENT_PATTERNS.some((re) => re.test(text)))
375
+ return true;
376
+ return false;
377
+ }
378
+ function parseFallbackModel(fallbackModel) {
379
+ if (!fallbackModel)
380
+ return;
381
+ const trimmed = fallbackModel.trim();
382
+ if (!trimmed)
383
+ return;
384
+ const slashIndex = trimmed.indexOf("/");
385
+ if (slashIndex > 0) {
386
+ return {
387
+ providerId: trimmed.slice(0, slashIndex),
388
+ modelId: trimmed.slice(slashIndex + 1)
389
+ };
390
+ }
391
+ return { modelId: trimmed };
392
+ }
393
+
394
+ // src/env/agent/agent-component.ts
200
395
  init_global_hook_manager();
201
396
  init_context();
202
397
  init_workflow_hil();
@@ -403,6 +598,7 @@ class AgentComponent extends BaseComponent {
403
598
  abortControllers = new Map;
404
599
  defaultTools = [];
405
600
  doomLoopCaches = new Map;
601
+ fallbackState = new Map;
406
602
  configComponent;
407
603
  configWatcher;
408
604
  messageConverter = new SessionMessageConverter;
@@ -882,6 +1078,7 @@ class AgentComponent extends BaseComponent {
882
1078
  tools: this.getAvailableTools(agent, effectiveContext),
883
1079
  systemPrompt: resolvedSystemPrompt ?? agent.config.systemPrompt ?? "You are a helpful assistant.",
884
1080
  context: effectiveContext,
1081
+ _runId: runId,
885
1082
  ...cacheSnapshot ? { _cacheSnapshot: cacheSnapshot } : {}
886
1083
  };
887
1084
  let historyMessageCount = 0;
@@ -1295,6 +1492,7 @@ class AgentComponent extends BaseComponent {
1295
1492
  this.aborted.delete(runId);
1296
1493
  this.abortControllers.delete(runId);
1297
1494
  this.doomLoopCaches.delete(runId);
1495
+ this.fallbackState.delete(runId);
1298
1496
  if (result.error) {
1299
1497
  this.pushEnvEvent({
1300
1498
  type: "agent.error",
@@ -1484,45 +1682,78 @@ class AgentComponent extends BaseComponent {
1484
1682
  async invokeLLM(ctx) {
1485
1683
  logger2.debug("[invokeLLM] Starting LLM invocation");
1486
1684
  if (this.llmComponent?.invoke) {
1685
+ const llm = this.llmComponent;
1487
1686
  const messages = await this.buildMessages(ctx);
1488
1687
  const convertedMessages = messages.map(toLLMMessage);
1489
1688
  logger2.debug(`[invokeLLM] Calling LLMComponent.invoke with ${convertedMessages.length} messages`);
1490
- try {
1491
- const llmPromise = this.llmComponent.invoke({
1492
- messages: convertedMessages,
1493
- tools: ctx.tools.map((t) => ({
1494
- name: t.name,
1495
- description: t.description || "",
1496
- parameters: t.parameters ?? {}
1497
- })),
1498
- model: ctx.context.model,
1499
- context: {
1500
- sessionId: ctx.context.sessionId,
1501
- messageId: ctx.context.messageId
1502
- },
1503
- abortSignal: ctx.context.abort,
1504
- skipThresholdCheck: ctx.context.agentType === "sub",
1505
- ...ctx.context.toolChoice ? { toolChoice: ctx.context.toolChoice } : {}
1506
- });
1507
- const result = await withTimeout(llmPromise, 300000, "LLM invocation timeout after 300s");
1508
- logger2.debug("[invokeLLM] LLMComponent.invoke returned successfully");
1689
+ const runKey = ctx._runId ?? ctx.context.sessionId ?? "default-run";
1690
+ const sticky = this.fallbackState.get(runKey);
1691
+ const configuredFallback = this.resolveFallbackModel(ctx.context.fallbackModel);
1692
+ const activeModel = sticky?.activeModel ?? ctx.context.model;
1693
+ const invokeWithModel = (model, signal) => llm.invoke({
1694
+ messages: convertedMessages,
1695
+ tools: ctx.tools.map((t) => ({
1696
+ name: t.name,
1697
+ description: t.description || "",
1698
+ parameters: t.parameters ?? {}
1699
+ })),
1700
+ model,
1701
+ context: {
1702
+ sessionId: ctx.context.sessionId,
1703
+ messageId: ctx.context.messageId
1704
+ },
1705
+ abortSignal: signal,
1706
+ skipThresholdCheck: ctx.context.agentType === "sub",
1707
+ ...ctx.context.toolChoice ? { toolChoice: ctx.context.toolChoice } : {}
1708
+ });
1709
+ const startAttempt = (model, label) => {
1710
+ const attemptController = new AbortController;
1711
+ const signal = ctx.context.abort ? AbortSignal.any([ctx.context.abort, attemptController.signal]) : attemptController.signal;
1509
1712
  return {
1510
- content: result.output?.content || "",
1511
- reasoning: result.output?.reasoning,
1512
- toolCalls: result.output?.toolCalls?.map((tc) => ({
1513
- id: tc.id,
1514
- function: tc.function ? {
1515
- name: tc.function.name,
1516
- arguments: typeof tc.function.arguments === "string" ? tc.function.arguments : JSON.stringify(tc.function.arguments)
1517
- } : undefined,
1518
- name: tc.name,
1519
- arguments: tc.arguments
1520
- })),
1521
- finishReason: result.output?.finishReason
1713
+ promise: withTimeout(invokeWithModel(model, signal), 300000, label),
1714
+ cancel: () => {
1715
+ try {
1716
+ attemptController.abort();
1717
+ } catch {}
1718
+ }
1522
1719
  };
1720
+ };
1721
+ let primaryAttempt;
1722
+ try {
1723
+ primaryAttempt = startAttempt(activeModel, "LLM invocation timeout after 300s");
1724
+ const result = await primaryAttempt.promise;
1725
+ logger2.debug("[invokeLLM] LLMComponent.invoke returned successfully");
1726
+ return this.normalizeLLMOutput(result);
1523
1727
  } catch (error) {
1524
1728
  logger2.error("[invokeLLM] LLMComponent.invoke threw an error:", error);
1525
- throw error;
1729
+ primaryAttempt?.cancel();
1730
+ if (ctx.context.abort?.aborted) {
1731
+ throw error;
1732
+ }
1733
+ const alreadyDowngraded = sticky?.fallbackModel !== undefined;
1734
+ const canFallback = !alreadyDowngraded && !!configuredFallback && !AgentComponent.sameModel(configuredFallback, activeModel) && isFallbackEligibleError(error, true);
1735
+ if (!canFallback) {
1736
+ throw error;
1737
+ }
1738
+ logger2.warn(`[invokeLLM] primary model "${activeModel ?? "(default)"}" failed with a fallback-eligible error; downgrading to fallback model "${configuredFallback}" for run ${runKey}`);
1739
+ this.fallbackState.set(runKey, {
1740
+ activeModel: configuredFallback,
1741
+ fallbackModel: configuredFallback
1742
+ });
1743
+ const fallbackAttempt = startAttempt(configuredFallback, "LLM invocation timeout after 300s (fallback)");
1744
+ try {
1745
+ const result = await fallbackAttempt.promise;
1746
+ logger2.info(`[invokeLLM] fallback model "${configuredFallback}" succeeded for run ${runKey}`);
1747
+ return this.normalizeLLMOutput(result);
1748
+ } catch (fallbackError) {
1749
+ fallbackAttempt.cancel();
1750
+ if (fallbackError instanceof ContextError) {
1751
+ logger2.warn(`[invokeLLM] fallback model "${configuredFallback}" hit a context limit; re-throwing ContextError so the compaction pipeline can handle it`);
1752
+ throw fallbackError;
1753
+ }
1754
+ logger2.error(`[invokeLLM] fallback model "${configuredFallback}" also failed; re-throwing the ORIGINAL primary error`, fallbackError);
1755
+ throw error;
1756
+ }
1526
1757
  }
1527
1758
  }
1528
1759
  logger2.warn("[invokeLLM] No LLMComponent available, using mock");
@@ -1531,6 +1762,53 @@ class AgentComponent extends BaseComponent {
1531
1762
  finishReason: "stop"
1532
1763
  };
1533
1764
  }
1765
+ resolveFallbackModel(explicit) {
1766
+ const readConfig = (key) => {
1767
+ const raw2 = this.configComponent?.get?.(key);
1768
+ if (typeof raw2 !== "string")
1769
+ return;
1770
+ const trimmed = raw2.trim();
1771
+ return trimmed ? trimmed : undefined;
1772
+ };
1773
+ const raw = explicit?.trim() || readConfig("llm.fallbackModel");
1774
+ if (!raw)
1775
+ return;
1776
+ const parsed = parseFallbackModel(raw);
1777
+ if (!parsed?.modelId)
1778
+ return;
1779
+ if (parsed.providerId)
1780
+ return `${parsed.providerId}/${parsed.modelId}`;
1781
+ const provider = readConfig("llm.fallbackProvider");
1782
+ return provider ? `${provider}/${parsed.modelId}` : parsed.modelId;
1783
+ }
1784
+ static sameModel(a, b) {
1785
+ const norm = (value) => {
1786
+ if (!value)
1787
+ return "";
1788
+ const trimmed = value.trim();
1789
+ const slash = trimmed.indexOf("/");
1790
+ return slash >= 0 ? trimmed.slice(slash + 1) : trimmed;
1791
+ };
1792
+ const left = norm(a);
1793
+ const right = norm(b);
1794
+ return !!left && left === right;
1795
+ }
1796
+ normalizeLLMOutput(result) {
1797
+ return {
1798
+ content: result.output?.content || "",
1799
+ reasoning: result.output?.reasoning,
1800
+ toolCalls: result.output?.toolCalls?.map((tc) => ({
1801
+ id: tc.id,
1802
+ function: tc.function ? {
1803
+ name: tc.function.name,
1804
+ arguments: typeof tc.function.arguments === "string" ? tc.function.arguments : JSON.stringify(tc.function.arguments)
1805
+ } : undefined,
1806
+ name: tc.name,
1807
+ arguments: tc.arguments
1808
+ })),
1809
+ finishReason: result.output?.finishReason
1810
+ };
1811
+ }
1534
1812
  parseToolCallArguments(toolCall) {
1535
1813
  const rawArgs = toolCall.function?.arguments ?? toolCall.arguments;
1536
1814
  return safeParseToolArgs(rawArgs);
@@ -1579,10 +1857,13 @@ class AgentComponent extends BaseComponent {
1579
1857
  },
1580
1858
  sessionId: toolEventSessionId
1581
1859
  });
1860
+ const effectiveRunModel = this.fallbackState.get(ctx._runId ?? ctx.context.sessionId ?? "default-run")?.activeModel ?? ctx.context.model;
1582
1861
  const toolContext = {
1583
1862
  session_id: ctx.context.sessionId,
1584
1863
  message_id: ctx.context.messageId,
1585
1864
  abort: ctx.context.abort,
1865
+ model: effectiveRunModel,
1866
+ fallbackModel: ctx.context.fallbackModel,
1586
1867
  workdir: ctx.context.metadata?.workdir,
1587
1868
  metadata: ctx.context.metadata
1588
1869
  };
@@ -2,12 +2,12 @@ import {
2
2
  WorkflowRepository,
3
3
  migrateEmptyTagsToDefault,
4
4
  rowToWorkflow
5
- } from "./roy-agent-core-vwzan9v0.js";
6
- import"./roy-agent-core-gc6wcd7z.js";
5
+ } from "./roy-agent-core-r5wt1h3c.js";
6
+ import"./roy-agent-core-mcy5apay.js";
7
7
  import"./roy-agent-core-rvxg1wps.js";
8
- import"./roy-agent-core-386wa4wy.js";
9
- import"./roy-agent-core-6awgfh3x.js";
10
- import"./roy-agent-core-jnszp0jq.js";
8
+ import"./roy-agent-core-qq96p0tj.js";
9
+ import"./roy-agent-core-7f7t9wwp.js";
10
+ import"./roy-agent-core-85xyctnb.js";
11
11
  import"./roy-agent-core-fs0mn2jk.js";
12
12
  export {
13
13
  rowToWorkflow,
@@ -2,11 +2,11 @@ import {
2
2
  getEnvContextOrEmpty,
3
3
  init_env_context,
4
4
  setCurrentTaskId
5
- } from "./roy-agent-core-hfyxv2kx.js";
5
+ } from "./roy-agent-core-7cbpmk4q.js";
6
6
  import {
7
7
  createLogger,
8
8
  init_logger
9
- } from "./roy-agent-core-6awgfh3x.js";
9
+ } from "./roy-agent-core-7f7t9wwp.js";
10
10
 
11
11
  // src/env/task/tools/task-types.ts
12
12
  import { z } from "zod";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DAGManager,
3
3
  init_dag_manager
4
- } from "./roy-agent-core-p6a4v4fq.js";
4
+ } from "./roy-agent-core-mds8tqd0.js";
5
5
 
6
6
  // src/env/workflow/utils/node-output-contracts.ts
7
7
  var VIRTUAL_OUTPUT_FIELD = "output";
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  TracedAs,
3
3
  init_decorator
4
- } from "./roy-agent-core-386wa4wy.js";
4
+ } from "./roy-agent-core-qq96p0tj.js";
5
5
  import {
6
6
  createLogger,
7
7
  init_logger
8
- } from "./roy-agent-core-6awgfh3x.js";
8
+ } from "./roy-agent-core-7f7t9wwp.js";
9
9
  import {
10
10
  __legacyDecorateClassTS
11
11
  } from "./roy-agent-core-fs0mn2jk.js";
@@ -8,7 +8,7 @@ import {
8
8
  } from "./roy-agent-core-qxnbvgwe.js";
9
9
  import {
10
10
  BaseComponent
11
- } from "./roy-agent-core-gtdtzbs7.js";
11
+ } from "./roy-agent-core-pgvcf91v.js";
12
12
  import {
13
13
  __require
14
14
  } from "./roy-agent-core-fs0mn2jk.js";
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  TempFileManager
3
- } from "../../shared/@ai-setting/roy-agent-core-wzp4tbsn.js";
4
- import"../../shared/@ai-setting/roy-agent-core-6awgfh3x.js";
5
- import"../../shared/@ai-setting/roy-agent-core-jnszp0jq.js";
3
+ } from "../../shared/@ai-setting/roy-agent-core-jvv2h3d6.js";
4
+ import"../../shared/@ai-setting/roy-agent-core-7f7t9wwp.js";
5
+ import"../../shared/@ai-setting/roy-agent-core-85xyctnb.js";
6
6
  import"../../shared/@ai-setting/roy-agent-core-fs0mn2jk.js";
7
7
  export {
8
8
  TempFileManager
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-setting/roy-agent-core",
3
- "version": "1.7.62",
3
+ "version": "1.7.64",
4
4
  "type": "module",
5
5
  "description": "Core SDK for roy-agent - Environment, Components, Tools, Sessions, Tasks",
6
6
  "main": "./dist/index.js",
@@ -1,10 +0,0 @@
1
- import {
2
- TagRepository
3
- } from "./roy-agent-core-gc6wcd7z.js";
4
- import"./roy-agent-core-386wa4wy.js";
5
- import"./roy-agent-core-6awgfh3x.js";
6
- import"./roy-agent-core-jnszp0jq.js";
7
- import"./roy-agent-core-fs0mn2jk.js";
8
- export {
9
- TagRepository
10
- };