@ai-setting/roy-agent-core 1.7.61 → 1.7.63

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 (129) hide show
  1. package/dist/config/index.js +8 -8
  2. package/dist/env/agent/agent-component.d.ts +33 -0
  3. package/dist/env/agent/agent-component.js +42 -0
  4. package/dist/env/agent/index.js +19 -16
  5. package/dist/env/agent/types.d.ts +17 -0
  6. package/dist/env/commands/index.js +8 -8
  7. package/dist/env/context/index.js +4 -4
  8. package/dist/env/debug/index.js +8 -8
  9. package/dist/env/error-reply.d.ts +53 -1
  10. package/dist/env/error-reply.js +25 -0
  11. package/dist/env/event-source/cli-command-handler.js +17 -0
  12. package/dist/env/event-source/event-source-handlers.js +59 -0
  13. package/dist/env/event-source/event-store.js +18 -0
  14. package/dist/env/event-source/idempotency-key.js +20 -0
  15. package/dist/env/event-source/index.js +31 -25
  16. package/dist/env/hook/index.js +6 -6
  17. package/dist/env/index.js +53 -46
  18. package/dist/env/lark-mention-utils.js +9 -0
  19. package/dist/env/llm/adapter-pi-ai.d.ts +47 -0
  20. package/dist/env/llm/index.js +10 -9
  21. package/dist/env/llm/model-fallback.d.ts +54 -0
  22. package/dist/env/llm/redact.d.ts +39 -0
  23. package/dist/env/llm/types.d.ts +13 -0
  24. package/dist/env/log-trace/index.js +8 -8
  25. package/dist/env/log-trace/logger.js +39 -0
  26. package/dist/env/mcp/index.js +9 -9
  27. package/dist/env/mcp/tool/index.js +2 -2
  28. package/dist/env/memory/index.js +9 -9
  29. package/dist/env/memory/plugin/index.js +2 -2
  30. package/dist/env/plugin/index.js +9 -9
  31. package/dist/env/prompt/index.js +8 -8
  32. package/dist/env/session/index.js +12 -11
  33. package/dist/env/session/storage/index.js +6 -5
  34. package/dist/env/skill/index.js +8 -8
  35. package/dist/env/task/delegate/delegate-tool.d.ts +27 -1
  36. package/dist/env/task/delegate/delegate-tool.js +42 -0
  37. package/dist/env/task/delegate/index.js +13 -11
  38. package/dist/env/task/index.js +16 -15
  39. package/dist/env/task/mcp/index.js +4 -4
  40. package/dist/env/task/plugins/index.js +11 -11
  41. package/dist/env/task/plugins/lark-card-patch-notifier.js +42 -0
  42. package/dist/env/task/storage/index.js +4 -4
  43. package/dist/env/task/tools/index.js +4 -4
  44. package/dist/env/tool/built-in/index.js +4 -4
  45. package/dist/env/tool/index.js +12 -11
  46. package/dist/env/tool/types.d.ts +13 -0
  47. package/dist/env/tool/types.js +1 -0
  48. package/dist/env/workflow/engine/index.js +13 -13
  49. package/dist/env/workflow/hooks/index.js +8 -8
  50. package/dist/env/workflow/index.js +24 -23
  51. package/dist/env/workflow/nodes/index.js +3 -3
  52. package/dist/env/workflow/plugins/index.js +9 -9
  53. package/dist/env/workflow/service/index.js +3 -3
  54. package/dist/env/workflow/storage/index.js +4 -4
  55. package/dist/env/workflow/tools/index.js +16 -15
  56. package/dist/env/workflow/utils/index.js +5 -5
  57. package/dist/index.js +71 -62
  58. package/dist/shared/@ai-setting/{roy-agent-core-m2tv4pj0.js → roy-agent-core-03k5drfp.js} +212 -172
  59. package/dist/shared/@ai-setting/{roy-agent-core-dythsgkn.js → roy-agent-core-06jakebr.js} +2 -2
  60. package/dist/shared/@ai-setting/{roy-agent-core-jsn21cb9.js → roy-agent-core-084zthqx.js} +1 -1
  61. package/dist/shared/@ai-setting/{roy-agent-core-vmfk4m1v.js → roy-agent-core-1dnsk6ht.js} +3 -3
  62. package/dist/shared/@ai-setting/{roy-agent-core-5565cvw8.js → roy-agent-core-2cw72f16.js} +11 -6
  63. package/dist/shared/@ai-setting/{roy-agent-core-x1m0gs0q.js → roy-agent-core-2hkyp51n.js} +1 -1
  64. package/dist/shared/@ai-setting/{roy-agent-core-q212q0w1.js → roy-agent-core-2pma868e.js} +4 -4
  65. package/dist/shared/@ai-setting/{roy-agent-core-mw0bc9g6.js → roy-agent-core-32ck9rqt.js} +2 -2
  66. package/dist/shared/@ai-setting/{roy-agent-core-bdzdw1g3.js → roy-agent-core-33hn1beg.js} +1 -1
  67. package/dist/shared/@ai-setting/{roy-agent-core-2qkrpc7m.js → roy-agent-core-386wa4wy.js} +1 -1
  68. package/dist/shared/@ai-setting/{roy-agent-core-gtb4fj8j.js → roy-agent-core-5hq4v41q.js} +12 -10
  69. package/dist/shared/@ai-setting/{roy-agent-core-khc23qs1.js → roy-agent-core-5mrynf9g.js} +1 -1
  70. package/dist/shared/@ai-setting/{roy-agent-core-4m5spt7m.js → roy-agent-core-60f7h284.js} +5 -5
  71. package/dist/shared/@ai-setting/{roy-agent-core-y0k9kaxz.js → roy-agent-core-6awgfh3x.js} +1 -1
  72. package/dist/shared/@ai-setting/{roy-agent-core-ygfjgk9b.js → roy-agent-core-6wxww10t.js} +2 -2
  73. package/dist/shared/@ai-setting/{roy-agent-core-xc0es9zc.js → roy-agent-core-79gyka2q.js} +2 -2
  74. package/dist/shared/@ai-setting/{roy-agent-core-expvav8a.js → roy-agent-core-7tce05jt.js} +1 -1
  75. package/dist/shared/@ai-setting/{roy-agent-core-z51jktet.js → roy-agent-core-a08dpf71.js} +17 -2
  76. package/dist/shared/@ai-setting/{roy-agent-core-22r4zmkw.js → roy-agent-core-a6cz4d23.js} +3 -3
  77. package/dist/shared/@ai-setting/{roy-agent-core-0f989bnp.js → roy-agent-core-anb53t3v.js} +3 -3
  78. package/dist/shared/@ai-setting/{roy-agent-core-ymcvsdzn.js → roy-agent-core-as0dd70m.js} +2 -2
  79. package/dist/shared/@ai-setting/{roy-agent-core-jrksyqb6.js → roy-agent-core-b4zdm2n4.js} +8 -8
  80. package/dist/shared/@ai-setting/{roy-agent-core-rnzm0tpf.js → roy-agent-core-bm3gav5d.js} +4 -4
  81. package/dist/shared/@ai-setting/{roy-agent-core-nd5171pv.js → roy-agent-core-bpvz1dqr.js} +8 -8
  82. package/dist/shared/@ai-setting/{roy-agent-core-aa514zm8.js → roy-agent-core-c4t4y18j.js} +5 -5
  83. package/dist/shared/@ai-setting/{roy-agent-core-sf9tsj0g.js → roy-agent-core-c57278kx.js} +1 -1
  84. package/dist/shared/@ai-setting/{roy-agent-core-e6k448ka.js → roy-agent-core-c8xvy6hj.js} +4 -4
  85. package/dist/shared/@ai-setting/{roy-agent-core-qgapy83x.js → roy-agent-core-cxpgd415.js} +6 -6
  86. package/dist/shared/@ai-setting/{roy-agent-core-g44nbgtt.js → roy-agent-core-dfqhc9ey.js} +2 -2
  87. package/dist/shared/@ai-setting/{roy-agent-core-6cyjps72.js → roy-agent-core-ebws32tv.js} +14 -14
  88. package/dist/shared/@ai-setting/{roy-agent-core-yr5eqyhz.js → roy-agent-core-g23yp3t1.js} +309 -59
  89. package/dist/shared/@ai-setting/roy-agent-core-g6pw4esq.js +473 -0
  90. package/dist/shared/@ai-setting/{roy-agent-core-3p59ap0x.js → roy-agent-core-gc6wcd7z.js} +1 -1
  91. package/dist/shared/@ai-setting/{roy-agent-core-s7w47mnn.js → roy-agent-core-gjsvehfs.js} +1 -1
  92. package/dist/shared/@ai-setting/{roy-agent-core-cndvj1hv.js → roy-agent-core-gnt23yx0.js} +30 -118
  93. package/dist/shared/@ai-setting/{roy-agent-core-9s3payp1.js → roy-agent-core-gtdtzbs7.js} +2 -2
  94. package/dist/shared/@ai-setting/{roy-agent-core-mhppywse.js → roy-agent-core-hczj1ryh.js} +4 -4
  95. package/dist/shared/@ai-setting/{roy-agent-core-qrjs2500.js → roy-agent-core-hfyxv2kx.js} +2 -2
  96. package/dist/shared/@ai-setting/{roy-agent-core-dg286rpd.js → roy-agent-core-hwkc0bg2.js} +1 -1
  97. package/dist/shared/@ai-setting/{roy-agent-core-bc3v8pw4.js → roy-agent-core-ja4sr63d.js} +6 -6
  98. package/dist/shared/@ai-setting/roy-agent-core-jagkferh.js +16 -0
  99. package/dist/shared/@ai-setting/roy-agent-core-jm136jzh.js +99 -0
  100. package/dist/shared/@ai-setting/{roy-agent-core-g5sw19fa.js → roy-agent-core-jw63js86.js} +1 -1
  101. package/dist/shared/@ai-setting/{roy-agent-core-8fy467qs.js → roy-agent-core-kmvw6b4v.js} +1 -1
  102. package/dist/shared/@ai-setting/{roy-agent-core-3bpntd80.js → roy-agent-core-kvq4a4p6.js} +2 -2
  103. package/dist/shared/@ai-setting/{roy-agent-core-yd85623y.js → roy-agent-core-m3w3ytxt.js} +2 -2
  104. package/dist/shared/@ai-setting/{roy-agent-core-64f22h1g.js → roy-agent-core-m880qz3y.js} +7 -1
  105. package/dist/shared/@ai-setting/{roy-agent-core-5knpegzr.js → roy-agent-core-mbwaxqs0.js} +3 -3
  106. package/dist/shared/@ai-setting/{roy-agent-core-tn96n4wz.js → roy-agent-core-mkpsz128.js} +4 -4
  107. package/dist/shared/@ai-setting/{roy-agent-core-9k8ms63r.js → roy-agent-core-mrrv80jy.js} +1 -1
  108. package/dist/shared/@ai-setting/roy-agent-core-ntn32q7j.js +72 -0
  109. package/dist/shared/@ai-setting/roy-agent-core-p37kh0kt.js +155 -0
  110. package/dist/shared/@ai-setting/{roy-agent-core-60p2380d.js → roy-agent-core-p6a4v4fq.js} +1 -1
  111. package/dist/shared/@ai-setting/{roy-agent-core-hf0t8agb.js → roy-agent-core-p8rf4z89.js} +1 -1
  112. package/dist/shared/@ai-setting/roy-agent-core-pnj0zh25.js +0 -0
  113. package/dist/shared/@ai-setting/{roy-agent-core-dp1hp24k.js → roy-agent-core-prnry2mw.js} +3 -3
  114. package/dist/shared/@ai-setting/{roy-agent-core-qw5fpa24.js → roy-agent-core-qmqe8ds3.js} +3 -3
  115. package/dist/shared/@ai-setting/{roy-agent-core-jsdqzfbj.js → roy-agent-core-rfhxj8v2.js} +1 -1
  116. package/dist/shared/@ai-setting/{roy-agent-core-j0x9yf96.js → roy-agent-core-sj4y3wdm.js} +3 -3
  117. package/dist/shared/@ai-setting/{roy-agent-core-ytnedzks.js → roy-agent-core-t6nx0rsz.js} +333 -1332
  118. package/dist/shared/@ai-setting/{roy-agent-core-xeqp659x.js → roy-agent-core-th92f833.js} +2 -2
  119. package/dist/shared/@ai-setting/{roy-agent-core-ajmgyawx.js → roy-agent-core-v7mwj8eq.js} +2 -2
  120. package/dist/shared/@ai-setting/roy-agent-core-va4m04e8.js +524 -0
  121. package/dist/shared/@ai-setting/{roy-agent-core-qpqqx1wd.js → roy-agent-core-vwzan9v0.js} +2 -2
  122. package/dist/shared/@ai-setting/{roy-agent-core-pj5tfmn5.js → roy-agent-core-w2ev3z5q.js} +12 -14
  123. package/dist/shared/@ai-setting/{roy-agent-core-kfmrfaft.js → roy-agent-core-wzp4tbsn.js} +1 -1
  124. package/dist/shared/@ai-setting/{roy-agent-core-n1ck0x1r.js → roy-agent-core-ye4bfzqg.js} +11 -11
  125. package/dist/shared/@ai-setting/{roy-agent-core-p2dpcyrz.js → roy-agent-core-zjgckbdd.js} +2 -2
  126. package/dist/shared/@ai-setting/{roy-agent-core-a5nh5q6v.js → roy-agent-core-zy8vkbnk.js} +1 -1
  127. package/dist/test-utils/child-process-mock.js +23 -0
  128. package/dist/utils/temp-file-manager/index.js +2 -2
  129. package/package.json +61 -1
@@ -1,22 +1,178 @@
1
1
  import {
2
2
  sniffImageMime
3
3
  } from "./roy-agent-core-zjdzk1gg.js";
4
+ import {
5
+ redactErrorForTransport,
6
+ redactSecrets
7
+ } from "./roy-agent-core-ntn32q7j.js";
4
8
  import {
5
9
  TracedAs,
6
10
  embedParamFilter,
7
11
  embedResultFilter,
8
12
  init_decorator,
9
13
  init_trace_filters
10
- } from "./roy-agent-core-2qkrpc7m.js";
14
+ } from "./roy-agent-core-386wa4wy.js";
11
15
  import {
12
16
  createLogger,
13
17
  init_logger
14
- } from "./roy-agent-core-y0k9kaxz.js";
18
+ } from "./roy-agent-core-6awgfh3x.js";
15
19
  import {
16
20
  __legacyDecorateClassTS,
17
21
  __require
18
22
  } from "./roy-agent-core-fs0mn2jk.js";
19
23
 
24
+ // src/env/llm/tool-args-parser.ts
25
+ init_logger();
26
+ var logger = createLogger("llm:tool-args-parser");
27
+ var ARG_KEY_RE = /<arg_key>([\s\S]*?)<\/arg_key>\s*<arg_value>([\s\S]*?)<\/arg_value>/g;
28
+ function salvageTextualToolArgs(raw) {
29
+ if (!raw.includes("<arg_key>"))
30
+ return;
31
+ const out = {};
32
+ let matched = false;
33
+ ARG_KEY_RE.lastIndex = 0;
34
+ let m;
35
+ while ((m = ARG_KEY_RE.exec(raw)) !== null) {
36
+ const key = m[1].trim();
37
+ if (!key)
38
+ continue;
39
+ const value = m[2];
40
+ try {
41
+ out[key] = JSON.parse(value);
42
+ } catch {
43
+ out[key] = value;
44
+ }
45
+ matched = true;
46
+ }
47
+ return matched ? out : undefined;
48
+ }
49
+ function stripTextualToolArgsMarkers(raw) {
50
+ return raw.replace(/<\/?arg_key>/g, "").replace(/<\/?arg_value>/g, "").replace(/<\/?tool_call>/g, "");
51
+ }
52
+ function parseToolArgsStrict(args) {
53
+ if (args && typeof args === "object" && !Array.isArray(args)) {
54
+ return { ok: true, args };
55
+ }
56
+ if (typeof args !== "string") {
57
+ return {
58
+ ok: false,
59
+ args: {},
60
+ error: `tool arguments must be a JSON object, got ${args === null ? "null" : typeof args}`
61
+ };
62
+ }
63
+ const raw = args.trim();
64
+ if (raw.length === 0) {
65
+ return { ok: true, args: {} };
66
+ }
67
+ const direct = tryParseObject(raw);
68
+ if (direct.ok) {
69
+ if (raw.includes("<arg_key>") || raw.includes("<arg_value>") || raw.includes("<tool_call>")) {
70
+ logger.warn("[parseToolArgsStrict] arguments 里出现上游文本工具调用标记,已清洗值中的 marker");
71
+ return { ok: true, args: sanitizeArgValues(direct.args), salvaged: true };
72
+ }
73
+ return { ok: true, args: direct.args };
74
+ }
75
+ if (raw.includes("<arg_key>") || raw.includes("<arg_value>")) {
76
+ const stripped = stripTextualToolArgsMarkers(raw);
77
+ const afterStrip = tryParseObject(stripped);
78
+ if (afterStrip.ok) {
79
+ logger.warn("[parseToolArgsStrict] 上游把文本工具调用标记混进了 arguments,已剥离 marker 后恢复");
80
+ return { ok: true, args: afterStrip.args, salvaged: true };
81
+ }
82
+ const salvaged = salvageTextualToolArgs(raw);
83
+ if (salvaged) {
84
+ logger.warn("[parseToolArgsStrict] 上游输出的是文本工具调用格式,已按 <arg_key>/<arg_value> 重建参数", { keys: Object.keys(salvaged).join(",") });
85
+ return { ok: true, args: salvaged, salvaged: true };
86
+ }
87
+ }
88
+ const nested = tryParseObject(raw);
89
+ if (!nested.ok && raw.length > 1) {
90
+ const rec = safeParseToolArgs(raw);
91
+ if (Object.keys(rec).length > 0) {
92
+ return { ok: true, args: rec, salvaged: true };
93
+ }
94
+ }
95
+ return {
96
+ ok: false,
97
+ args: {},
98
+ error: "tool arguments 不是合法 JSON(上游模型输出可能已损坏)。请重新调用该工具,确保 arguments 是合法 JSON 对象。" + ` 原始片段:${raw.slice(0, 200)}`
99
+ };
100
+ }
101
+ function sanitizeArgValues(args) {
102
+ const clean = (v) => {
103
+ if (typeof v === "string")
104
+ return stripTextualToolArgsMarkers(v);
105
+ if (Array.isArray(v))
106
+ return v.map(clean);
107
+ if (v && typeof v === "object") {
108
+ const out = {};
109
+ for (const [k, val] of Object.entries(v)) {
110
+ out[k] = clean(val);
111
+ }
112
+ return out;
113
+ }
114
+ return v;
115
+ };
116
+ return clean(args);
117
+ }
118
+ function tryParseObject(raw) {
119
+ try {
120
+ const parsed = JSON.parse(raw);
121
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
122
+ return { ok: true, args: parsed };
123
+ }
124
+ if (typeof parsed === "string") {
125
+ const twice = JSON.parse(parsed);
126
+ if (twice && typeof twice === "object" && !Array.isArray(twice)) {
127
+ return { ok: true, args: twice };
128
+ }
129
+ }
130
+ return { ok: false };
131
+ } catch {
132
+ return { ok: false };
133
+ }
134
+ }
135
+ var MAX_SAFE_DEPTH = 5;
136
+ function safeParseToolArgs(args, depth = 0) {
137
+ if (depth >= MAX_SAFE_DEPTH) {
138
+ logger.warn(`[safeParseToolArgs] Max recursion depth (${MAX_SAFE_DEPTH}) exceeded at depth ${depth}. ` + "Input may be malicious or abnormally deeply nested. Returning empty object.", { depth, argsType: typeof args });
139
+ return {};
140
+ }
141
+ if (typeof args === "object" && args !== null && !Array.isArray(args)) {
142
+ return args;
143
+ }
144
+ if (Array.isArray(args)) {
145
+ logger.debug(`[safeParseToolArgs] Input is an array. Tool arguments should be objects. Returning empty object.`, { depth, arrayLength: args.length });
146
+ return {};
147
+ }
148
+ if (typeof args === "string") {
149
+ try {
150
+ const parsed = JSON.parse(args);
151
+ if (typeof parsed === "string") {
152
+ logger.debug(`[safeParseToolArgs] Detected double/multi-stringified JSON at depth ${depth}. ` + "LLM may be double-stringifying tool arguments. Parsing recursively.", { depth, parsedLength: parsed.length });
153
+ return safeParseToolArgs(parsed, depth + 1);
154
+ }
155
+ if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
156
+ return parsed;
157
+ }
158
+ if (Array.isArray(parsed)) {
159
+ logger.debug(`[safeParseToolArgs] Parsed result is an array at depth ${depth}. ` + "Tool arguments should be objects, not arrays. Returning empty object.", { depth, parsedLength: parsed.length });
160
+ return {};
161
+ }
162
+ return { value: parsed };
163
+ } catch (e) {
164
+ logger.warn(`[safeParseToolArgs] JSON.parse failed at depth ${depth}`, {
165
+ parse_failed: true,
166
+ input_length: args.length,
167
+ depth,
168
+ error: e.message
169
+ });
170
+ return {};
171
+ }
172
+ }
173
+ return {};
174
+ }
175
+
20
176
  // src/env/llm/opencode-session.ts
21
177
  var OPENCODE_SESSION_ID_CACHE_MAX = 1000;
22
178
  var opencodeSessionIdCache = new Map;
@@ -200,7 +356,7 @@ function createReasoningDefenseHook(target) {
200
356
  }
201
357
 
202
358
  // src/env/llm/adapter-pi-ai.ts
203
- var logger = createLogger("llm:adapter-pi-ai");
359
+ var logger2 = createLogger("llm:adapter-pi-ai");
204
360
  var KNOWN_PROVIDER_APIS = {
205
361
  anthropic: {
206
362
  api: "anthropic-messages",
@@ -311,7 +467,7 @@ function resolveApiProtocol(provider, baseURL, explicitProtocol) {
311
467
  if (baseURL?.includes("/responses"))
312
468
  return "openai-responses";
313
469
  if (baseURL?.includes("anthropic")) {
314
- logger.warn(`[adapter-pi-ai] provider "${provider}" 的协议靠 baseURL 含 "anthropic" 推断为 anthropic-messages;` + `建议在 KNOWN_PROVIDER_APIS 或调用处显式声明 apiProtocol(Task #4383 P1)`, { provider, inferred_api_protocol: "anthropic-messages", base_url: baseURL });
470
+ logger2.warn(`[adapter-pi-ai] provider "${provider}" 的协议靠 baseURL 含 "anthropic" 推断为 anthropic-messages;` + `建议在 KNOWN_PROVIDER_APIS 或调用处显式声明 apiProtocol(Task #4383 P1)`, { provider, inferred_api_protocol: "anthropic-messages", base_url: baseURL });
315
471
  return "anthropic-messages";
316
472
  }
317
473
  return KNOWN_PROVIDER_APIS[provider]?.api || "openai-completions";
@@ -334,7 +490,7 @@ function resolveModelReasoning(provider, modelId, capabilities, apiProtocol) {
334
490
  const key = `${provider}:${apiProtocol ?? "<unresolved>"}`;
335
491
  if (!warnedReasoningRefusals.has(key)) {
336
492
  warnedReasoningRefusals.add(key);
337
- logger.warn(`[adapter-pi-ai] provider "${provider}" (${apiProtocol ?? "unresolved"}) 的 capabilities.reasoning=true 被忽略:` + `该协议无法通过 compat pin 保持请求体字节一致,打开会破坏 prompt cache 前缀(Task #4403)`, { provider, model_id: modelId, api_protocol: apiProtocol });
493
+ logger2.warn(`[adapter-pi-ai] provider "${provider}" (${apiProtocol ?? "unresolved"}) 的 capabilities.reasoning=true 被忽略:` + `该协议无法通过 compat pin 保持请求体字节一致,打开会破坏 prompt cache 前缀(Task #4403)`, { provider, model_id: modelId, api_protocol: apiProtocol });
338
494
  }
339
495
  return false;
340
496
  }
@@ -371,6 +527,35 @@ function resolvePiModel(provider, modelId, baseURL, capabilities) {
371
527
  maxTokens: KNOWN_PROVIDER_APIS[provider]?.maxTokensLimit || 8192
372
528
  };
373
529
  }
530
+ var PI_MAX_RETRIES = 0;
531
+ function createResponseCapture() {
532
+ let last;
533
+ return {
534
+ onResponse: (response) => {
535
+ last = {
536
+ status: response?.status ?? 0,
537
+ headers: { ...response?.headers ?? {} }
538
+ };
539
+ },
540
+ captured: () => last
541
+ };
542
+ }
543
+ function buildProviderError(message, captured, knownSecrets = []) {
544
+ const err = new Error(redactSecrets(message, knownSecrets));
545
+ if (!captured)
546
+ return err;
547
+ const enriched = err;
548
+ if (captured.status)
549
+ enriched.statusCode = captured.status;
550
+ if (Object.keys(captured.headers).length > 0) {
551
+ enriched.responseHeaders = captured.headers;
552
+ }
553
+ enriched.cause = {
554
+ statusCode: captured.status,
555
+ responseHeaders: captured.headers
556
+ };
557
+ return enriched;
558
+ }
374
559
  function toPiMessages(messages) {
375
560
  const out = [];
376
561
  const ts = Date.now();
@@ -423,7 +608,7 @@ function safeJson(s) {
423
608
  try {
424
609
  return JSON.parse(s);
425
610
  } catch (e) {
426
- logger.warn(`[safeJson] JSON.parse failed`, {
611
+ logger2.warn(`[safeJson] JSON.parse failed`, {
427
612
  parse_failed: true,
428
613
  input_length: s.length,
429
614
  error: e.message
@@ -495,12 +680,14 @@ class PiAiAdapter {
495
680
  messages: toPiMessages(req.messages),
496
681
  tools: toPiTools(req.tools)
497
682
  };
683
+ const responseCapture = createResponseCapture();
498
684
  const msg = await complete(model, ctx, {
499
685
  apiKey: req.apiKey,
500
686
  baseURL: req.baseURL,
501
687
  temperature: req.temperature,
502
688
  maxTokens: req.maxTokens,
503
689
  signal: req.signal,
690
+ onResponse: responseCapture.onResponse,
504
691
  ...buildPiCacheOptions({
505
692
  apiProtocol: model.api,
506
693
  sessionId: req.sessionId,
@@ -510,8 +697,12 @@ class PiAiAdapter {
510
697
  provider: req.provider,
511
698
  modelId: req.modelId
512
699
  }),
700
+ maxRetries: PI_MAX_RETRIES,
513
701
  ...piRequestExtras(req)
514
702
  });
703
+ if (msg.stopReason === "error") {
704
+ throw buildProviderError(msg.errorMessage || "Provider returned an error stop reason", responseCapture.captured(), [req.apiKey]);
705
+ }
515
706
  return fromAssistantMessage(msg);
516
707
  }
517
708
  async stream(req) {
@@ -523,12 +714,14 @@ class PiAiAdapter {
523
714
  messages: toPiMessages(req.messages),
524
715
  tools: toPiTools(req.tools)
525
716
  };
717
+ const responseCapture = createResponseCapture();
526
718
  const eventStream = piStream(model, ctx, {
527
719
  apiKey: req.apiKey,
528
720
  baseURL: req.baseURL,
529
721
  temperature: req.temperature,
530
722
  maxTokens: req.maxTokens,
531
723
  signal: req.signal,
724
+ onResponse: responseCapture.onResponse,
532
725
  ...buildPiCacheOptions({
533
726
  apiProtocol: model.api,
534
727
  sessionId: req.sessionId,
@@ -538,9 +731,19 @@ class PiAiAdapter {
538
731
  provider: req.provider,
539
732
  modelId: req.modelId
540
733
  }),
734
+ maxRetries: PI_MAX_RETRIES,
541
735
  ...piRequestExtras(req)
542
736
  });
543
- return { events: eventStream, result: async () => fromAssistantMessage(await eventStream.result()) };
737
+ return {
738
+ events: eventStream,
739
+ result: async () => {
740
+ const msg = await eventStream.result();
741
+ if (msg.stopReason === "error") {
742
+ throw buildProviderError(msg.errorMessage || "Provider returned an error stop reason", responseCapture.captured(), [req.apiKey]);
743
+ }
744
+ return fromAssistantMessage(msg);
745
+ }
746
+ };
544
747
  }
545
748
  async embed(_req) {
546
749
  throw new EmbeddingNotSupportedError(this.name);
@@ -635,158 +838,6 @@ import { createGoogleGenerativeAI } from "@ai-sdk/google";
635
838
  import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
636
839
  init_logger();
637
840
 
638
- // src/env/llm/tool-args-parser.ts
639
- init_logger();
640
- var logger2 = createLogger("llm:tool-args-parser");
641
- var ARG_KEY_RE = /<arg_key>([\s\S]*?)<\/arg_key>\s*<arg_value>([\s\S]*?)<\/arg_value>/g;
642
- function salvageTextualToolArgs(raw) {
643
- if (!raw.includes("<arg_key>"))
644
- return;
645
- const out = {};
646
- let matched = false;
647
- ARG_KEY_RE.lastIndex = 0;
648
- let m;
649
- while ((m = ARG_KEY_RE.exec(raw)) !== null) {
650
- const key = m[1].trim();
651
- if (!key)
652
- continue;
653
- const value = m[2];
654
- try {
655
- out[key] = JSON.parse(value);
656
- } catch {
657
- out[key] = value;
658
- }
659
- matched = true;
660
- }
661
- return matched ? out : undefined;
662
- }
663
- function stripTextualToolArgsMarkers(raw) {
664
- return raw.replace(/<\/?arg_key>/g, "").replace(/<\/?arg_value>/g, "").replace(/<\/?tool_call>/g, "");
665
- }
666
- function parseToolArgsStrict(args) {
667
- if (args && typeof args === "object" && !Array.isArray(args)) {
668
- return { ok: true, args };
669
- }
670
- if (typeof args !== "string") {
671
- return {
672
- ok: false,
673
- args: {},
674
- error: `tool arguments must be a JSON object, got ${args === null ? "null" : typeof args}`
675
- };
676
- }
677
- const raw = args.trim();
678
- if (raw.length === 0) {
679
- return { ok: true, args: {} };
680
- }
681
- const direct = tryParseObject(raw);
682
- if (direct.ok) {
683
- if (raw.includes("<arg_key>") || raw.includes("<arg_value>") || raw.includes("<tool_call>")) {
684
- logger2.warn("[parseToolArgsStrict] arguments 里出现上游文本工具调用标记,已清洗值中的 marker");
685
- return { ok: true, args: sanitizeArgValues(direct.args), salvaged: true };
686
- }
687
- return { ok: true, args: direct.args };
688
- }
689
- if (raw.includes("<arg_key>") || raw.includes("<arg_value>")) {
690
- const stripped = stripTextualToolArgsMarkers(raw);
691
- const afterStrip = tryParseObject(stripped);
692
- if (afterStrip.ok) {
693
- logger2.warn("[parseToolArgsStrict] 上游把文本工具调用标记混进了 arguments,已剥离 marker 后恢复");
694
- return { ok: true, args: afterStrip.args, salvaged: true };
695
- }
696
- const salvaged = salvageTextualToolArgs(raw);
697
- if (salvaged) {
698
- logger2.warn("[parseToolArgsStrict] 上游输出的是文本工具调用格式,已按 <arg_key>/<arg_value> 重建参数", { keys: Object.keys(salvaged).join(",") });
699
- return { ok: true, args: salvaged, salvaged: true };
700
- }
701
- }
702
- const nested = tryParseObject(raw);
703
- if (!nested.ok && raw.length > 1) {
704
- const rec = safeParseToolArgs(raw);
705
- if (Object.keys(rec).length > 0) {
706
- return { ok: true, args: rec, salvaged: true };
707
- }
708
- }
709
- return {
710
- ok: false,
711
- args: {},
712
- error: "tool arguments 不是合法 JSON(上游模型输出可能已损坏)。请重新调用该工具,确保 arguments 是合法 JSON 对象。" + ` 原始片段:${raw.slice(0, 200)}`
713
- };
714
- }
715
- function sanitizeArgValues(args) {
716
- const clean = (v) => {
717
- if (typeof v === "string")
718
- return stripTextualToolArgsMarkers(v);
719
- if (Array.isArray(v))
720
- return v.map(clean);
721
- if (v && typeof v === "object") {
722
- const out = {};
723
- for (const [k, val] of Object.entries(v)) {
724
- out[k] = clean(val);
725
- }
726
- return out;
727
- }
728
- return v;
729
- };
730
- return clean(args);
731
- }
732
- function tryParseObject(raw) {
733
- try {
734
- const parsed = JSON.parse(raw);
735
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
736
- return { ok: true, args: parsed };
737
- }
738
- if (typeof parsed === "string") {
739
- const twice = JSON.parse(parsed);
740
- if (twice && typeof twice === "object" && !Array.isArray(twice)) {
741
- return { ok: true, args: twice };
742
- }
743
- }
744
- return { ok: false };
745
- } catch {
746
- return { ok: false };
747
- }
748
- }
749
- var MAX_SAFE_DEPTH = 5;
750
- function safeParseToolArgs(args, depth = 0) {
751
- if (depth >= MAX_SAFE_DEPTH) {
752
- logger2.warn(`[safeParseToolArgs] Max recursion depth (${MAX_SAFE_DEPTH}) exceeded at depth ${depth}. ` + "Input may be malicious or abnormally deeply nested. Returning empty object.", { depth, argsType: typeof args });
753
- return {};
754
- }
755
- if (typeof args === "object" && args !== null && !Array.isArray(args)) {
756
- return args;
757
- }
758
- if (Array.isArray(args)) {
759
- logger2.debug(`[safeParseToolArgs] Input is an array. Tool arguments should be objects. Returning empty object.`, { depth, arrayLength: args.length });
760
- return {};
761
- }
762
- if (typeof args === "string") {
763
- try {
764
- const parsed = JSON.parse(args);
765
- if (typeof parsed === "string") {
766
- logger2.debug(`[safeParseToolArgs] Detected double/multi-stringified JSON at depth ${depth}. ` + "LLM may be double-stringifying tool arguments. Parsing recursively.", { depth, parsedLength: parsed.length });
767
- return safeParseToolArgs(parsed, depth + 1);
768
- }
769
- if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
770
- return parsed;
771
- }
772
- if (Array.isArray(parsed)) {
773
- logger2.debug(`[safeParseToolArgs] Parsed result is an array at depth ${depth}. ` + "Tool arguments should be objects, not arrays. Returning empty object.", { depth, parsedLength: parsed.length });
774
- return {};
775
- }
776
- return { value: parsed };
777
- } catch (e) {
778
- logger2.warn(`[safeParseToolArgs] JSON.parse failed at depth ${depth}`, {
779
- parse_failed: true,
780
- input_length: args.length,
781
- depth,
782
- error: e.message
783
- });
784
- return {};
785
- }
786
- }
787
- return {};
788
- }
789
-
790
841
  // src/env/llm/llm-cache.ts
791
842
  function isOpenAICompatibleProvider(providerName) {
792
843
  return providerName === "openai-compatible" || providerName === "openai" || providerName.startsWith("minimax") || providerName === "deepseek" || providerName.startsWith("deepseek") || providerName === "glm" || providerName.startsWith("glm");
@@ -1577,22 +1628,11 @@ async function invoke(config, options, ctx) {
1577
1628
  return {
1578
1629
  toolCallId: "error-" + Date.now(),
1579
1630
  result: safeMessage,
1580
- isError: true
1631
+ isError: true,
1632
+ ...error instanceof Error ? { originalError: redactErrorForTransport(error, [config.apiKey]) } : {}
1581
1633
  };
1582
1634
  }
1583
1635
  }
1584
- function redactSecrets(text, knownSecrets = []) {
1585
- let out = text;
1586
- for (const secret of knownSecrets) {
1587
- if (secret && secret.length >= 8) {
1588
- out = out.split(secret).join("<redacted>");
1589
- }
1590
- }
1591
- out = out.replace(/\boc_sk_[A-Za-z0-9_-]{8,}\b/g, "<redacted>");
1592
- out = out.replace(/\bsk-(?:proj-)?[A-Za-z0-9_-]{16,}\b/g, "<redacted>");
1593
- out = out.replace(/\bBearer\s+[A-Za-z0-9._\-+/=]{12,}\b/g, "<redacted>");
1594
- return out;
1595
- }
1596
1636
  function resolveDefenseProtocol(providerId, baseURL) {
1597
1637
  if (providerId === "openai")
1598
1638
  return "openai-responses";
@@ -4,11 +4,11 @@ import {
4
4
  import {
5
5
  TracedAs,
6
6
  init_decorator
7
- } from "./roy-agent-core-2qkrpc7m.js";
7
+ } from "./roy-agent-core-386wa4wy.js";
8
8
  import {
9
9
  createLogger,
10
10
  init_logger
11
- } from "./roy-agent-core-y0k9kaxz.js";
11
+ } from "./roy-agent-core-6awgfh3x.js";
12
12
  import {
13
13
  __legacyDecorateClassTS
14
14
  } from "./roy-agent-core-fs0mn2jk.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createLogger,
3
3
  init_logger
4
- } from "./roy-agent-core-y0k9kaxz.js";
4
+ } from "./roy-agent-core-6awgfh3x.js";
5
5
 
6
6
  // src/env/mcp/tool/adapter.ts
7
7
  init_logger();
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  SessionMessageConverter
3
- } from "./roy-agent-core-jsdqzfbj.js";
3
+ } from "./roy-agent-core-rfhxj8v2.js";
4
4
  import {
5
5
  canonicalizeParts
6
- } from "./roy-agent-core-m2tv4pj0.js";
6
+ } from "./roy-agent-core-03k5drfp.js";
7
7
  import {
8
8
  createLogger,
9
9
  init_logger
10
- } from "./roy-agent-core-y0k9kaxz.js";
10
+ } from "./roy-agent-core-6awgfh3x.js";
11
11
  import {
12
12
  __require
13
13
  } from "./roy-agent-core-fs0mn2jk.js";
@@ -6,7 +6,7 @@ import {
6
6
  PiAiAdapter,
7
7
  invoke,
8
8
  invokeNonStream
9
- } from "./roy-agent-core-m2tv4pj0.js";
9
+ } from "./roy-agent-core-03k5drfp.js";
10
10
  import {
11
11
  ContextError,
12
12
  ErrorCodes
@@ -17,12 +17,12 @@ import {
17
17
  } from "./roy-agent-core-7hh0brvs.js";
18
18
  import {
19
19
  BaseComponent
20
- } from "./roy-agent-core-9s3payp1.js";
20
+ } from "./roy-agent-core-gtdtzbs7.js";
21
21
  import {
22
22
  LLMHookPoints,
23
23
  globalHookManager,
24
24
  init_global_hook_manager
25
- } from "./roy-agent-core-ajmgyawx.js";
25
+ } from "./roy-agent-core-v7mwj8eq.js";
26
26
  import {
27
27
  TracedAs,
28
28
  embedParamFilter,
@@ -32,11 +32,11 @@ import {
32
32
  llmInvokeParamFilter,
33
33
  llmInvokeResultFilter,
34
34
  wrapFunction
35
- } from "./roy-agent-core-2qkrpc7m.js";
35
+ } from "./roy-agent-core-386wa4wy.js";
36
36
  import {
37
37
  createLogger,
38
38
  init_logger
39
- } from "./roy-agent-core-y0k9kaxz.js";
39
+ } from "./roy-agent-core-6awgfh3x.js";
40
40
  import {
41
41
  __legacyDecorateClassTS,
42
42
  __require
@@ -720,6 +720,8 @@ class LLMComponent extends BaseComponent {
720
720
  const llmKeys = [
721
721
  "llm.defaultModel",
722
722
  "llm.defaultProvider",
723
+ "llm.fallbackModel",
724
+ "llm.fallbackProvider",
723
725
  "llm.temperature",
724
726
  "llm.maxTokens",
725
727
  "llm.topP",
@@ -789,12 +791,15 @@ class LLMComponent extends BaseComponent {
789
791
  const knownKeys = new Set([
790
792
  "llm.defaultModel",
791
793
  "llm.defaultProvider",
794
+ "llm.fallbackModel",
795
+ "llm.fallbackProvider",
792
796
  "llm.temperature",
793
797
  "llm.maxTokens",
794
798
  "llm.topP",
795
799
  "llm.stream",
796
800
  "llm.options",
797
801
  "llm.default",
802
+ "llm.fallback",
798
803
  "llm.providers",
799
804
  "llm.limits",
800
805
  "llm.capabilities"
@@ -1015,7 +1020,7 @@ class LLMComponent extends BaseComponent {
1015
1020
  cacheRetention: chatReq.cacheRetention
1016
1021
  }, { abort: ctx.abortSignal });
1017
1022
  if (result.isError) {
1018
- throw new Error(result.result);
1023
+ throw result.originalError ? new Error(result.result, { cause: result.originalError }) : new Error(result.result);
1019
1024
  }
1020
1025
  try {
1021
1026
  const parsed = JSON.parse(result.result);
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createLogger,
3
3
  init_logger
4
- } from "./roy-agent-core-y0k9kaxz.js";
4
+ } from "./roy-agent-core-6awgfh3x.js";
5
5
  import {
6
6
  __require
7
7
  } from "./roy-agent-core-fs0mn2jk.js";
@@ -4,7 +4,7 @@ import {
4
4
  } from "./roy-agent-core-rvv6ydff.js";
5
5
  import {
6
6
  BaseComponent
7
- } from "./roy-agent-core-9s3payp1.js";
7
+ } from "./roy-agent-core-gtdtzbs7.js";
8
8
  import {
9
9
  __require
10
10
  } from "./roy-agent-core-fs0mn2jk.js";
@@ -590,7 +590,7 @@ class DebugComponent extends BaseComponent {
590
590
  }
591
591
  async getLiveTrace(traceId) {
592
592
  try {
593
- const { getTracerProvider } = await import("./roy-agent-core-s7w47mnn.js");
593
+ const { getTracerProvider } = await import("./roy-agent-core-gjsvehfs.js");
594
594
  const provider = getTracerProvider();
595
595
  if (!provider.isInitialized()) {
596
596
  await provider.initialize();
@@ -635,7 +635,7 @@ class DebugComponent extends BaseComponent {
635
635
  }
636
636
  async listLiveTraces(limit = 20) {
637
637
  try {
638
- const { getTracerProvider } = await import("./roy-agent-core-s7w47mnn.js");
638
+ const { getTracerProvider } = await import("./roy-agent-core-gjsvehfs.js");
639
639
  const provider = getTracerProvider();
640
640
  if (!provider.isInitialized()) {
641
641
  await provider.initialize();
@@ -653,7 +653,7 @@ class DebugComponent extends BaseComponent {
653
653
  }
654
654
  async formatLiveTrace(traceId) {
655
655
  try {
656
- const { getTracerProvider } = await import("./roy-agent-core-s7w47mnn.js");
656
+ const { getTracerProvider } = await import("./roy-agent-core-gjsvehfs.js");
657
657
  const provider = getTracerProvider();
658
658
  if (!provider.isInitialized()) {
659
659
  await provider.initialize();
@@ -4,11 +4,11 @@ import {
4
4
  } from "./roy-agent-core-7hh0brvs.js";
5
5
  import {
6
6
  BaseComponent
7
- } from "./roy-agent-core-9s3payp1.js";
7
+ } from "./roy-agent-core-gtdtzbs7.js";
8
8
  import {
9
9
  createLogger,
10
10
  init_logger
11
- } from "./roy-agent-core-y0k9kaxz.js";
11
+ } from "./roy-agent-core-6awgfh3x.js";
12
12
 
13
13
  // src/env/commands/commands-component.ts
14
14
  import path2 from "path";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  init_env_context,
3
3
  init_env_event
4
- } from "./roy-agent-core-qrjs2500.js";
4
+ } from "./roy-agent-core-hfyxv2kx.js";
5
5
  import {
6
6
  __esm
7
7
  } from "./roy-agent-core-fs0mn2jk.js";
@@ -5,7 +5,7 @@ import {
5
5
  init_logger,
6
6
  init_tracer_provider,
7
7
  simplifyFilePath
8
- } from "./roy-agent-core-y0k9kaxz.js";
8
+ } from "./roy-agent-core-6awgfh3x.js";
9
9
  import {
10
10
  __esm
11
11
  } from "./roy-agent-core-fs0mn2jk.js";