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

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 (138) hide show
  1. package/dist/config/index.js +8 -8
  2. package/dist/env/agent/agent-component.js +41 -0
  3. package/dist/env/agent/index.js +18 -16
  4. package/dist/env/commands/index.js +8 -8
  5. package/dist/env/context/index.js +4 -4
  6. package/dist/env/debug/index.js +8 -8
  7. package/dist/env/error-reply.js +18 -0
  8. package/dist/env/event-source/cli-command-handler.d.ts +90 -0
  9. package/dist/env/event-source/cli-command-handler.js +17 -0
  10. package/dist/env/event-source/event-source-handlers.d.ts +1 -0
  11. package/dist/env/event-source/event-source-handlers.js +58 -0
  12. package/dist/env/event-source/event-store.js +18 -0
  13. package/dist/env/event-source/idempotency-key.js +20 -0
  14. package/dist/env/event-source/index.d.ts +3 -1
  15. package/dist/env/event-source/index.js +37 -22
  16. package/dist/env/event-source/types.d.ts +21 -1
  17. package/dist/env/hook/index.js +6 -6
  18. package/dist/env/index.js +54 -48
  19. package/dist/env/lark-mention-utils.js +9 -0
  20. package/dist/env/llm/index.js +9 -9
  21. package/dist/env/log-trace/index.d.ts +1 -1
  22. package/dist/env/log-trace/index.js +12 -8
  23. package/dist/env/log-trace/logger.d.ts +2 -0
  24. package/dist/env/log-trace/logger.js +39 -0
  25. package/dist/env/mcp/index.js +9 -9
  26. package/dist/env/mcp/tool/index.js +2 -2
  27. package/dist/env/memory/index.js +9 -9
  28. package/dist/env/memory/plugin/index.js +2 -2
  29. package/dist/env/plugin/index.js +9 -9
  30. package/dist/env/prompt/index.js +8 -8
  31. package/dist/env/session/index.js +11 -11
  32. package/dist/env/session/storage/index.js +5 -5
  33. package/dist/env/skill/index.js +8 -8
  34. package/dist/env/task/delegate/delegate-tool.js +42 -0
  35. package/dist/env/task/delegate/index.js +13 -11
  36. package/dist/env/task/index.js +17 -16
  37. package/dist/env/task/mcp/index.d.ts +16 -0
  38. package/dist/env/task/mcp/index.js +222 -0
  39. package/dist/env/task/mcp/task-mcp-server.d.ts +142 -0
  40. package/dist/env/task/plugins/index.d.ts +1 -0
  41. package/dist/env/task/plugins/index.js +47 -12
  42. package/dist/env/task/plugins/lark-card-patch-notifier.js +42 -0
  43. package/dist/env/task/storage/index.js +4 -4
  44. package/dist/env/task/storage/migrations/log-migration.d.ts +19 -0
  45. package/dist/env/task/storage/sqlite-task-store.d.ts +29 -0
  46. package/dist/env/task/task-component.d.ts +48 -3
  47. package/dist/env/task/tools/index.js +4 -4
  48. package/dist/env/task/tools/task-types.d.ts +60 -11
  49. package/dist/env/tool/built-in/index.js +4 -4
  50. package/dist/env/tool/index.js +12 -11
  51. package/dist/env/tool/types.js +1 -0
  52. package/dist/env/workflow/engine/index.js +13 -13
  53. package/dist/env/workflow/hooks/index.js +8 -8
  54. package/dist/env/workflow/index.js +23 -23
  55. package/dist/env/workflow/nodes/index.js +3 -3
  56. package/dist/env/workflow/plugins/index.js +9 -9
  57. package/dist/env/workflow/service/index.js +3 -3
  58. package/dist/env/workflow/storage/index.js +4 -4
  59. package/dist/env/workflow/tools/index.js +15 -15
  60. package/dist/env/workflow/tools/run-workflow.d.ts +30 -0
  61. package/dist/env/workflow/utils/index.js +5 -5
  62. package/dist/env/workflow/utils/session-recovery.d.ts +27 -0
  63. package/dist/index.js +91 -73
  64. package/dist/shared/@ai-setting/{roy-agent-core-ygn5tzt1.js → roy-agent-core-06jakebr.js} +2 -2
  65. package/dist/shared/@ai-setting/{roy-agent-core-m68z3pw1.js → roy-agent-core-084zthqx.js} +1 -1
  66. package/dist/shared/@ai-setting/{roy-agent-core-cyefe8z5.js → roy-agent-core-2hkyp51n.js} +1 -1
  67. package/dist/shared/@ai-setting/{roy-agent-core-029r8kdw.js → roy-agent-core-2pma868e.js} +4 -4
  68. package/dist/shared/@ai-setting/{roy-agent-core-c7w2h47a.js → roy-agent-core-2veqhrxa.js} +3 -3
  69. package/dist/shared/@ai-setting/{roy-agent-core-t64nmayv.js → roy-agent-core-32ck9rqt.js} +2 -2
  70. package/dist/shared/@ai-setting/{roy-agent-core-m97jn2ra.js → roy-agent-core-33hn1beg.js} +1 -1
  71. package/dist/shared/@ai-setting/{roy-agent-core-8p63s836.js → roy-agent-core-386wa4wy.js} +1 -1
  72. package/dist/shared/@ai-setting/{roy-agent-core-kq9pz2a7.js → roy-agent-core-48h4zh60.js} +4 -4
  73. package/dist/shared/@ai-setting/{roy-agent-core-eanq305k.js → roy-agent-core-5bj0xfjk.js} +13 -27
  74. package/dist/shared/@ai-setting/{roy-agent-core-7q4wdze2.js → roy-agent-core-5mrynf9g.js} +1 -1
  75. package/dist/shared/@ai-setting/{roy-agent-core-rt115qfc.js → roy-agent-core-6awgfh3x.js} +14 -4
  76. package/dist/shared/@ai-setting/{roy-agent-core-9zhkdg6w.js → roy-agent-core-6wxww10t.js} +2 -2
  77. package/dist/shared/@ai-setting/{roy-agent-core-baaa4wtp.js → roy-agent-core-79gyka2q.js} +2 -2
  78. package/dist/shared/@ai-setting/{roy-agent-core-ytd5eztz.js → roy-agent-core-7tce05jt.js} +1 -1
  79. package/dist/shared/@ai-setting/{roy-agent-core-x6c45yqd.js → roy-agent-core-99nwgj84.js} +1 -1
  80. package/dist/shared/@ai-setting/roy-agent-core-9nvyffxg.js +414 -0
  81. package/dist/shared/@ai-setting/{roy-agent-core-e1w17tht.js → roy-agent-core-9qgrc9dy.js} +158 -158
  82. package/dist/shared/@ai-setting/{roy-agent-core-2ctyjy62.js → roy-agent-core-a08dpf71.js} +17 -2
  83. package/dist/shared/@ai-setting/{roy-agent-core-e250355z.js → roy-agent-core-a6cz4d23.js} +3 -3
  84. package/dist/shared/@ai-setting/{roy-agent-core-tze5596n.js → roy-agent-core-anb53t3v.js} +3 -3
  85. package/dist/shared/@ai-setting/{roy-agent-core-caevk7xd.js → roy-agent-core-arx535cs.js} +30 -8
  86. package/dist/shared/@ai-setting/{roy-agent-core-vh0qzb24.js → roy-agent-core-as0dd70m.js} +36 -15
  87. package/dist/shared/@ai-setting/{roy-agent-core-w93z6a42.js → roy-agent-core-bpvz1dqr.js} +12 -12
  88. package/dist/shared/@ai-setting/{roy-agent-core-ck60j1q9.js → roy-agent-core-bxkjk7zx.js} +2 -1
  89. package/dist/shared/@ai-setting/{roy-agent-core-hs41gx9w.js → roy-agent-core-c4t4y18j.js} +5 -5
  90. package/dist/shared/@ai-setting/{roy-agent-core-t4x089js.js → roy-agent-core-c57278kx.js} +1 -1
  91. package/dist/shared/@ai-setting/{roy-agent-core-em4hks9t.js → roy-agent-core-c8xvy6hj.js} +4 -4
  92. package/dist/shared/@ai-setting/{roy-agent-core-991pk4ss.js → roy-agent-core-cqpd41gf.js} +18 -16
  93. package/dist/shared/@ai-setting/{roy-agent-core-psg6f1v6.js → roy-agent-core-cxpgd415.js} +6 -6
  94. package/dist/shared/@ai-setting/{roy-agent-core-vgdhxbx3.js → roy-agent-core-dfqhc9ey.js} +2 -2
  95. package/dist/shared/@ai-setting/{roy-agent-core-6bradb0j.js → roy-agent-core-fqandv0a.js} +9 -107
  96. package/dist/shared/@ai-setting/{roy-agent-core-en2xqxs9.js → roy-agent-core-fr296a53.js} +39 -14
  97. package/dist/shared/@ai-setting/{roy-agent-core-rcgvmtms.js → roy-agent-core-gc6wcd7z.js} +1 -1
  98. package/dist/shared/@ai-setting/{roy-agent-core-7nb23tdd.js → roy-agent-core-gjsvehfs.js} +1 -1
  99. package/dist/shared/@ai-setting/{roy-agent-core-0kn3zt1t.js → roy-agent-core-gtdtzbs7.js} +2 -2
  100. package/dist/shared/@ai-setting/{roy-agent-core-84rs0c8d.js → roy-agent-core-gz2jnaan.js} +7 -7
  101. package/dist/shared/@ai-setting/{roy-agent-core-0yn7a78e.js → roy-agent-core-h3fwjbhp.js} +14 -14
  102. package/dist/shared/@ai-setting/{roy-agent-core-4096f575.js → roy-agent-core-hczj1ryh.js} +4 -4
  103. package/dist/shared/@ai-setting/{roy-agent-core-syyw58p9.js → roy-agent-core-hfyxv2kx.js} +2 -2
  104. package/dist/shared/@ai-setting/{roy-agent-core-d75t8gea.js → roy-agent-core-hwkc0bg2.js} +1 -1
  105. package/dist/shared/@ai-setting/{roy-agent-core-vath15kt.js → roy-agent-core-ja4sr63d.js} +6 -6
  106. package/dist/shared/@ai-setting/roy-agent-core-jagkferh.js +16 -0
  107. package/dist/shared/@ai-setting/roy-agent-core-jm136jzh.js +99 -0
  108. package/dist/shared/@ai-setting/{roy-agent-core-14bq77wr.js → roy-agent-core-jw63js86.js} +1 -1
  109. package/dist/shared/@ai-setting/{roy-agent-core-89sxsrc7.js → roy-agent-core-kmvw6b4v.js} +1 -1
  110. package/dist/shared/@ai-setting/{roy-agent-core-47s81t6g.js → roy-agent-core-kvq4a4p6.js} +2 -2
  111. package/dist/shared/@ai-setting/{roy-agent-core-c36335nw.js → roy-agent-core-m3w3ytxt.js} +15 -3
  112. package/dist/shared/@ai-setting/{roy-agent-core-64f22h1g.js → roy-agent-core-m880qz3y.js} +7 -1
  113. package/dist/shared/@ai-setting/{roy-agent-core-2fk8c9ax.js → roy-agent-core-mbwaxqs0.js} +3 -3
  114. package/dist/shared/@ai-setting/{roy-agent-core-jjhw9am6.js → roy-agent-core-mkpsz128.js} +4 -4
  115. package/dist/shared/@ai-setting/{roy-agent-core-20m8je6e.js → roy-agent-core-mrrv80jy.js} +1 -1
  116. package/dist/shared/@ai-setting/{roy-agent-core-6q5m1qk5.js → roy-agent-core-nmn853z0.js} +333 -1183
  117. package/dist/shared/@ai-setting/roy-agent-core-p37kh0kt.js +155 -0
  118. package/dist/shared/@ai-setting/{roy-agent-core-08njdcpj.js → roy-agent-core-p6a4v4fq.js} +1 -1
  119. package/dist/shared/@ai-setting/{roy-agent-core-gksw1gjb.js → roy-agent-core-p8rf4z89.js} +1 -1
  120. package/dist/shared/@ai-setting/roy-agent-core-pnj0zh25.js +0 -0
  121. package/dist/shared/@ai-setting/{roy-agent-core-q4gdfypk.js → roy-agent-core-prnry2mw.js} +3 -3
  122. package/dist/shared/@ai-setting/{roy-agent-core-84xtww7d.js → roy-agent-core-qmqe8ds3.js} +3 -3
  123. package/dist/shared/@ai-setting/{roy-agent-core-txwptxk1.js → roy-agent-core-sj4y3wdm.js} +3 -3
  124. package/dist/shared/@ai-setting/{roy-agent-core-fbjd7bt6.js → roy-agent-core-th92f833.js} +64 -29
  125. package/dist/shared/@ai-setting/{roy-agent-core-yphwdm9x.js → roy-agent-core-v7mwj8eq.js} +2 -2
  126. package/dist/shared/@ai-setting/{roy-agent-core-5f7myqnb.js → roy-agent-core-vvb4cyyy.js} +11 -5
  127. package/dist/shared/@ai-setting/{roy-agent-core-jjxdmedn.js → roy-agent-core-vwzan9v0.js} +2 -2
  128. package/dist/shared/@ai-setting/{roy-agent-core-fw6k4w1h.js → roy-agent-core-w2ev3z5q.js} +12 -14
  129. package/dist/shared/@ai-setting/roy-agent-core-w2h6xt6k.js +473 -0
  130. package/dist/shared/@ai-setting/{roy-agent-core-n0p0hwgd.js → roy-agent-core-wzp4tbsn.js} +1 -1
  131. package/dist/shared/@ai-setting/{roy-agent-core-ge87xbas.js → roy-agent-core-x1d6edkh.js} +1 -1
  132. package/dist/shared/@ai-setting/{roy-agent-core-8bngppw0.js → roy-agent-core-ye4bfzqg.js} +13 -13
  133. package/dist/shared/@ai-setting/{roy-agent-core-geh6j7bw.js → roy-agent-core-zjgckbdd.js} +2 -2
  134. package/dist/shared/@ai-setting/{roy-agent-core-hefarcp0.js → roy-agent-core-zy8vkbnk.js} +1 -1
  135. package/dist/test-utils/child-process-mock.js +23 -0
  136. package/dist/utils/temp-file-manager/index.js +2 -2
  137. package/package.json +76 -1
  138. /package/dist/shared/@ai-setting/{roy-agent-core-3ztzc83c.js → roy-agent-core-5enxfga2.js} +0 -0
@@ -7,16 +7,168 @@ import {
7
7
  embedResultFilter,
8
8
  init_decorator,
9
9
  init_trace_filters
10
- } from "./roy-agent-core-8p63s836.js";
10
+ } from "./roy-agent-core-386wa4wy.js";
11
11
  import {
12
12
  createLogger,
13
13
  init_logger
14
- } from "./roy-agent-core-rt115qfc.js";
14
+ } from "./roy-agent-core-6awgfh3x.js";
15
15
  import {
16
16
  __legacyDecorateClassTS,
17
17
  __require
18
18
  } from "./roy-agent-core-fs0mn2jk.js";
19
19
 
20
+ // src/env/llm/tool-args-parser.ts
21
+ init_logger();
22
+ var logger = createLogger("llm:tool-args-parser");
23
+ var ARG_KEY_RE = /<arg_key>([\s\S]*?)<\/arg_key>\s*<arg_value>([\s\S]*?)<\/arg_value>/g;
24
+ function salvageTextualToolArgs(raw) {
25
+ if (!raw.includes("<arg_key>"))
26
+ return;
27
+ const out = {};
28
+ let matched = false;
29
+ ARG_KEY_RE.lastIndex = 0;
30
+ let m;
31
+ while ((m = ARG_KEY_RE.exec(raw)) !== null) {
32
+ const key = m[1].trim();
33
+ if (!key)
34
+ continue;
35
+ const value = m[2];
36
+ try {
37
+ out[key] = JSON.parse(value);
38
+ } catch {
39
+ out[key] = value;
40
+ }
41
+ matched = true;
42
+ }
43
+ return matched ? out : undefined;
44
+ }
45
+ function stripTextualToolArgsMarkers(raw) {
46
+ return raw.replace(/<\/?arg_key>/g, "").replace(/<\/?arg_value>/g, "").replace(/<\/?tool_call>/g, "");
47
+ }
48
+ function parseToolArgsStrict(args) {
49
+ if (args && typeof args === "object" && !Array.isArray(args)) {
50
+ return { ok: true, args };
51
+ }
52
+ if (typeof args !== "string") {
53
+ return {
54
+ ok: false,
55
+ args: {},
56
+ error: `tool arguments must be a JSON object, got ${args === null ? "null" : typeof args}`
57
+ };
58
+ }
59
+ const raw = args.trim();
60
+ if (raw.length === 0) {
61
+ return { ok: true, args: {} };
62
+ }
63
+ const direct = tryParseObject(raw);
64
+ if (direct.ok) {
65
+ if (raw.includes("<arg_key>") || raw.includes("<arg_value>") || raw.includes("<tool_call>")) {
66
+ logger.warn("[parseToolArgsStrict] arguments 里出现上游文本工具调用标记,已清洗值中的 marker");
67
+ return { ok: true, args: sanitizeArgValues(direct.args), salvaged: true };
68
+ }
69
+ return { ok: true, args: direct.args };
70
+ }
71
+ if (raw.includes("<arg_key>") || raw.includes("<arg_value>")) {
72
+ const stripped = stripTextualToolArgsMarkers(raw);
73
+ const afterStrip = tryParseObject(stripped);
74
+ if (afterStrip.ok) {
75
+ logger.warn("[parseToolArgsStrict] 上游把文本工具调用标记混进了 arguments,已剥离 marker 后恢复");
76
+ return { ok: true, args: afterStrip.args, salvaged: true };
77
+ }
78
+ const salvaged = salvageTextualToolArgs(raw);
79
+ if (salvaged) {
80
+ logger.warn("[parseToolArgsStrict] 上游输出的是文本工具调用格式,已按 <arg_key>/<arg_value> 重建参数", { keys: Object.keys(salvaged).join(",") });
81
+ return { ok: true, args: salvaged, salvaged: true };
82
+ }
83
+ }
84
+ const nested = tryParseObject(raw);
85
+ if (!nested.ok && raw.length > 1) {
86
+ const rec = safeParseToolArgs(raw);
87
+ if (Object.keys(rec).length > 0) {
88
+ return { ok: true, args: rec, salvaged: true };
89
+ }
90
+ }
91
+ return {
92
+ ok: false,
93
+ args: {},
94
+ error: "tool arguments 不是合法 JSON(上游模型输出可能已损坏)。请重新调用该工具,确保 arguments 是合法 JSON 对象。" + ` 原始片段:${raw.slice(0, 200)}`
95
+ };
96
+ }
97
+ function sanitizeArgValues(args) {
98
+ const clean = (v) => {
99
+ if (typeof v === "string")
100
+ return stripTextualToolArgsMarkers(v);
101
+ if (Array.isArray(v))
102
+ return v.map(clean);
103
+ if (v && typeof v === "object") {
104
+ const out = {};
105
+ for (const [k, val] of Object.entries(v)) {
106
+ out[k] = clean(val);
107
+ }
108
+ return out;
109
+ }
110
+ return v;
111
+ };
112
+ return clean(args);
113
+ }
114
+ function tryParseObject(raw) {
115
+ try {
116
+ const parsed = JSON.parse(raw);
117
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
118
+ return { ok: true, args: parsed };
119
+ }
120
+ if (typeof parsed === "string") {
121
+ const twice = JSON.parse(parsed);
122
+ if (twice && typeof twice === "object" && !Array.isArray(twice)) {
123
+ return { ok: true, args: twice };
124
+ }
125
+ }
126
+ return { ok: false };
127
+ } catch {
128
+ return { ok: false };
129
+ }
130
+ }
131
+ var MAX_SAFE_DEPTH = 5;
132
+ function safeParseToolArgs(args, depth = 0) {
133
+ if (depth >= MAX_SAFE_DEPTH) {
134
+ 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 });
135
+ return {};
136
+ }
137
+ if (typeof args === "object" && args !== null && !Array.isArray(args)) {
138
+ return args;
139
+ }
140
+ if (Array.isArray(args)) {
141
+ logger.debug(`[safeParseToolArgs] Input is an array. Tool arguments should be objects. Returning empty object.`, { depth, arrayLength: args.length });
142
+ return {};
143
+ }
144
+ if (typeof args === "string") {
145
+ try {
146
+ const parsed = JSON.parse(args);
147
+ if (typeof parsed === "string") {
148
+ logger.debug(`[safeParseToolArgs] Detected double/multi-stringified JSON at depth ${depth}. ` + "LLM may be double-stringifying tool arguments. Parsing recursively.", { depth, parsedLength: parsed.length });
149
+ return safeParseToolArgs(parsed, depth + 1);
150
+ }
151
+ if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
152
+ return parsed;
153
+ }
154
+ if (Array.isArray(parsed)) {
155
+ 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 });
156
+ return {};
157
+ }
158
+ return { value: parsed };
159
+ } catch (e) {
160
+ logger.warn(`[safeParseToolArgs] JSON.parse failed at depth ${depth}`, {
161
+ parse_failed: true,
162
+ input_length: args.length,
163
+ depth,
164
+ error: e.message
165
+ });
166
+ return {};
167
+ }
168
+ }
169
+ return {};
170
+ }
171
+
20
172
  // src/env/llm/opencode-session.ts
21
173
  var OPENCODE_SESSION_ID_CACHE_MAX = 1000;
22
174
  var opencodeSessionIdCache = new Map;
@@ -200,7 +352,7 @@ function createReasoningDefenseHook(target) {
200
352
  }
201
353
 
202
354
  // src/env/llm/adapter-pi-ai.ts
203
- var logger = createLogger("llm:adapter-pi-ai");
355
+ var logger2 = createLogger("llm:adapter-pi-ai");
204
356
  var KNOWN_PROVIDER_APIS = {
205
357
  anthropic: {
206
358
  api: "anthropic-messages",
@@ -311,7 +463,7 @@ function resolveApiProtocol(provider, baseURL, explicitProtocol) {
311
463
  if (baseURL?.includes("/responses"))
312
464
  return "openai-responses";
313
465
  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 });
466
+ 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
467
  return "anthropic-messages";
316
468
  }
317
469
  return KNOWN_PROVIDER_APIS[provider]?.api || "openai-completions";
@@ -334,7 +486,7 @@ function resolveModelReasoning(provider, modelId, capabilities, apiProtocol) {
334
486
  const key = `${provider}:${apiProtocol ?? "<unresolved>"}`;
335
487
  if (!warnedReasoningRefusals.has(key)) {
336
488
  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 });
489
+ 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
490
  }
339
491
  return false;
340
492
  }
@@ -423,7 +575,7 @@ function safeJson(s) {
423
575
  try {
424
576
  return JSON.parse(s);
425
577
  } catch (e) {
426
- logger.warn(`[safeJson] JSON.parse failed`, {
578
+ logger2.warn(`[safeJson] JSON.parse failed`, {
427
579
  parse_failed: true,
428
580
  input_length: s.length,
429
581
  error: e.message
@@ -635,158 +787,6 @@ import { createGoogleGenerativeAI } from "@ai-sdk/google";
635
787
  import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
636
788
  init_logger();
637
789
 
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
790
  // src/env/llm/llm-cache.ts
791
791
  function isOpenAICompatibleProvider(providerName) {
792
792
  return providerName === "openai-compatible" || providerName === "openai" || providerName.startsWith("minimax") || providerName === "deepseek" || providerName.startsWith("deepseek") || providerName === "glm" || providerName.startsWith("glm");
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  TracedAs,
3
3
  init_decorator
4
- } from "./roy-agent-core-8p63s836.js";
4
+ } from "./roy-agent-core-386wa4wy.js";
5
5
  import {
6
6
  __legacyDecorateClassTS,
7
7
  __require
@@ -32,6 +32,21 @@ function createCompatibleDatabase(path) {
32
32
  }
33
33
  return db;
34
34
  }
35
+ var SCHEMA_SQL = `
36
+ CREATE TABLE IF NOT EXISTS event_store (
37
+ event_id TEXT PRIMARY KEY,
38
+ es_type TEXT NOT NULL,
39
+ sender_id TEXT NOT NULL,
40
+ text TEXT,
41
+ metadata TEXT NOT NULL,
42
+ raw_event TEXT,
43
+ created_at INTEGER NOT NULL
44
+ );
45
+
46
+ CREATE INDEX IF NOT EXISTS idx_es_sender_time
47
+ ON event_store (es_type, sender_id, created_at DESC);
48
+ `;
49
+
35
50
  class EventStoreImpl {
36
51
  db;
37
52
  insertStmt;
@@ -156,4 +171,4 @@ function resetSharedEventStore() {
156
171
  sharedEventStore = null;
157
172
  }
158
173
 
159
- export { EventStoreImpl, setSharedEventStore, getSharedEventStore, resetSharedEventStore };
174
+ export { SCHEMA_SQL, EventStoreImpl, setSharedEventStore, getSharedEventStore, resetSharedEventStore };
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  TagRepository
3
- } from "./roy-agent-core-rcgvmtms.js";
4
- import"./roy-agent-core-8p63s836.js";
5
- import"./roy-agent-core-rt115qfc.js";
3
+ } from "./roy-agent-core-gc6wcd7z.js";
4
+ import"./roy-agent-core-386wa4wy.js";
5
+ import"./roy-agent-core-6awgfh3x.js";
6
6
  import"./roy-agent-core-jnszp0jq.js";
7
7
  import"./roy-agent-core-fs0mn2jk.js";
8
8
  export {
@@ -3,11 +3,11 @@ import {
3
3
  } from "./roy-agent-core-7hh0brvs.js";
4
4
  import {
5
5
  BaseComponent
6
- } from "./roy-agent-core-0kn3zt1t.js";
6
+ } from "./roy-agent-core-gtdtzbs7.js";
7
7
  import {
8
8
  init_decorator,
9
9
  init_trace_filters
10
- } from "./roy-agent-core-8p63s836.js";
10
+ } from "./roy-agent-core-386wa4wy.js";
11
11
  import {
12
12
  createLogger,
13
13
  getTracerProvider,
@@ -18,7 +18,7 @@ import {
18
18
  propagation,
19
19
  setConfigComponent,
20
20
  setQuietMode
21
- } from "./roy-agent-core-rt115qfc.js";
21
+ } from "./roy-agent-core-6awgfh3x.js";
22
22
  import {
23
23
  SQLiteSpanStorage,
24
24
  init_span_storage
@@ -97,23 +97,45 @@ function findLastCallMessage(messages) {
97
97
  }
98
98
  function parseNodeOutputs(messages) {
99
99
  const outputs = new Map;
100
- let lastStartNodeId = null;
100
+ const startedNodes = new Set;
101
101
  for (const msg of messages) {
102
102
  const metadata = msg.metadata;
103
103
  const msgType = metadata?.type;
104
104
  if (msgType === "workflow.node.start" || msgType === "workflow.node.call") {
105
- lastStartNodeId = getWorkflowNodeIdFromMetadata(metadata) ?? null;
106
- } else if ((msgType === "workflow.node.end" || msgType === "workflow.node.result") && lastStartNodeId) {
107
- try {
108
- outputs.set(lastStartNodeId, JSON.parse(msg.content));
109
- } catch {
110
- outputs.set(lastStartNodeId, msg.content);
105
+ const startedId = getWorkflowNodeIdFromMetadata(metadata);
106
+ if (startedId) {
107
+ startedNodes.add(startedId);
111
108
  }
112
- lastStartNodeId = null;
109
+ continue;
113
110
  }
111
+ if (msgType !== "workflow.node.end" && msgType !== "workflow.node.result") {
112
+ continue;
113
+ }
114
+ const nodeId = getWorkflowNodeIdFromMetadata(metadata);
115
+ if (!nodeId) {
116
+ continue;
117
+ }
118
+ if (msgType === "workflow.node.result" && !startedNodes.has(nodeId)) {
119
+ continue;
120
+ }
121
+ outputs.set(nodeId, extractNodeOutputValue(msg));
114
122
  }
115
123
  return outputs;
116
124
  }
125
+ function extractNodeOutputValue(msg) {
126
+ const parts = msg.parts;
127
+ if (Array.isArray(parts)) {
128
+ const part = parts.find((p) => p && p["type"] === "workflow-node-end" && ("output" in p));
129
+ if (part && part["output"] !== undefined) {
130
+ return part["output"];
131
+ }
132
+ }
133
+ try {
134
+ return JSON.parse(msg.content);
135
+ } catch {
136
+ return msg.content;
137
+ }
138
+ }
117
139
  function hasPendingAskUser(messages) {
118
140
  if (messages.length === 0)
119
141
  return false;
@@ -2,14 +2,33 @@ import {
2
2
  getEnvContextOrEmpty,
3
3
  init_env_context,
4
4
  setCurrentTaskId
5
- } from "./roy-agent-core-syyw58p9.js";
5
+ } from "./roy-agent-core-hfyxv2kx.js";
6
6
  import {
7
7
  createLogger,
8
8
  init_logger
9
- } from "./roy-agent-core-rt115qfc.js";
9
+ } from "./roy-agent-core-6awgfh3x.js";
10
10
 
11
11
  // src/env/task/tools/task-types.ts
12
12
  import { z } from "zod";
13
+ var UNKNOWN_PROJECT_PATH = "unknown";
14
+ var UNKNOWN_TASK_CONTEXT = '{"type":"unknown"}';
15
+ function taskIdShape() {
16
+ return {
17
+ task_id: z.number().describe("Task ID")
18
+ };
19
+ }
20
+ function normaliseLegacyTaskId(raw) {
21
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw))
22
+ return raw;
23
+ const obj = raw;
24
+ if (obj.task_id === undefined && obj.id !== undefined) {
25
+ return { ...obj, task_id: obj.id };
26
+ }
27
+ return obj;
28
+ }
29
+ function withLegacyTaskId(shape) {
30
+ return z.preprocess(normaliseLegacyTaskId, z.object({ ...taskIdShape(), ...shape }));
31
+ }
13
32
  var CreateTaskToolSchema = z.object({
14
33
  title: z.string().describe("Task title"),
15
34
  description: z.string().optional().describe("Task description"),
@@ -18,7 +37,7 @@ var CreateTaskToolSchema = z.object({
18
37
  goals_and_expected_deliverables: z.string().optional().describe("Goals and expected deliverables"),
19
38
  due_date: z.string().optional().describe("Due date (ISO format)"),
20
39
  tags: z.array(z.string()).optional().describe("Task tags (for search, stored in task.tags JSON field)"),
21
- project_path: z.string().describe("Project root path for task positioning. " + "Used to locate the project space for this task. " + "Use 'unknown' if unknown."),
40
+ project_path: z.string().default("unknown").describe("Project root path for task positioning. " + "Used to locate the project space for this task. " + "Use 'unknown' if unknown. (Defaults to 'unknown'.)"),
22
41
  parent_task_id: z.union([z.number(), z.null()]).optional().describe(`父任务 ID(可选)。不传或传 null 时,创建根任务(root task)。
23
42
  ` + `如需将任务挂载到某个父任务下,传入对应父任务 ID。
24
43
  ` + `**调用前必须先调用 task_tree(depth=2)** 查看现有任务树结构,避免重复创建根任务、避免孤儿任务。
@@ -28,11 +47,10 @@ var CreateTaskToolSchema = z.object({
28
47
  ` + ` C. 新建根任务 → 省略 parent_task_id(让树根 ≤10)
29
48
  ` + `如何找到 parent_task_id:使用 task_tree(depth=2) 获取的树形结构,
30
49
  ` + "根据节点 id 选择合适的父任务 ID(来自 tree 输出,**不要硬编码**数字)。"),
31
- context: z.string().describe("JSON string with time-space positioning information for task continuity. " + "This field is crucial for Agent task handoff. " + "Core fields: worktree_path (git worktree path), branch (current branch), type (feature/bug/refactor/chore). " + 'Example for coding: {"worktree_path": "/path/worktree", "branch": "feature/xyz", "type": "feature"}. ' + 'Example for other: {"type": "general"}. ' + `If unknown, use '{}' or '{"type":"unknown"}'. ` + "IMPORTANT: Must be a valid JSON string!")
50
+ context: z.string().default('{"type":"unknown"}').describe("JSON string with time-space positioning information for task continuity. " + "This field is crucial for Agent task handoff. " + "Core fields: worktree_path (git worktree path), branch (current branch), type (feature/bug/refactor/chore). " + 'Example for coding: {"worktree_path": "/path/worktree", "branch": "feature/xyz", "type": "feature"}. ' + 'Example for other: {"type": "general"}. ' + `If unknown, use '{}' or '{"type":"unknown"}'. ` + "IMPORTANT: Must be a valid JSON string!")
32
51
  });
33
- var GetTaskToolSchema = z.object({
34
- task_id: z.number().describe("Task ID"),
35
- include_operations: z.boolean().optional().default(false).describe("Include operation records")
52
+ var GetTaskToolSchema = withLegacyTaskId({
53
+ include_operations: z.boolean().optional().default(true).describe("Include operation records (milestones / process log) with the task. " + "Defaults to true — the task's operation history is part of its detail. " + "Pass false for a lean task-only response.")
36
54
  });
37
55
  var ListTasksToolSchema = z.object({
38
56
  status: z.enum(["todo", "active", "completed", "paused", "cancelled", "archived"]).optional(),
@@ -54,8 +72,7 @@ var SearchTasksToolSchema = z.object({
54
72
  depth: z.number().optional().describe("检索层级深度:0=只根任务,1=根+一层子任务,2=根+二层子任务,-1 或忽略=全部"),
55
73
  include_archived: z.boolean().optional().default(false).describe("是否包含已归档任务(status=archived 的任务默认被排除)")
56
74
  });
57
- var UpdateTaskToolSchema = z.object({
58
- task_id: z.number().describe("Task ID"),
75
+ var UpdateTaskToolSchema = withLegacyTaskId({
59
76
  title: z.string().optional(),
60
77
  description: z.string().optional(),
61
78
  status: z.enum(["todo", "active", "completed", "paused", "cancelled", "archived"]).optional(),
@@ -73,8 +90,7 @@ var UpdateTaskToolSchema = z.object({
73
90
  var DeleteTaskToolSchema = z.object({
74
91
  task_id: z.number().describe("Task ID")
75
92
  });
76
- var CompleteTaskToolSchema = z.object({
77
- task_id: z.number().describe("Task ID"),
93
+ var CompleteTaskToolSchema = withLegacyTaskId({
78
94
  deliverable_storage_path: z.string().optional().describe("交付物的寻址地址(路径 / URL / 分支名等)。" + "调用本工具前,请先读取任务的 goal(description)和 delivery(goals_and_expected_deliverables)栏位," + "建议验证目标和交付物是否符合预期,然后将实际交付物的寻址地址填入此参数。")
79
95
  });
80
96
  var BatchArchiveToolSchema = z.object({
@@ -362,7 +378,9 @@ function createTaskTool(taskComponent) {
362
378
  let enrichedContext = params.context;
363
379
  const envParentTaskId = getEnvContextOrEmpty().parentTaskId;
364
380
  const effectiveParentTaskId = params.parent_task_id !== undefined && params.parent_task_id !== null ? params.parent_task_id : envParentTaskId !== undefined && envParentTaskId !== null && Number.isInteger(envParentTaskId) && envParentTaskId > 0 ? envParentTaskId : undefined;
365
- let inheritedProjectPath = params.project_path && params.project_path.trim() !== "" ? params.project_path : undefined;
381
+ const callerProjectPath = params.project_path && params.project_path.trim() !== "" ? params.project_path : undefined;
382
+ const callerProjectPathIsExplicit = callerProjectPath !== undefined && callerProjectPath !== UNKNOWN_PROJECT_PATH;
383
+ let inheritedProjectPath = callerProjectPathIsExplicit ? callerProjectPath : undefined;
366
384
  let inheritedTags = params.tags;
367
385
  let inheritedContext;
368
386
  if (effectiveParentTaskId !== undefined) {
@@ -396,7 +414,8 @@ function createTaskTool(taskComponent) {
396
414
  }
397
415
  }
398
416
  try {
399
- const ctxObj = params.context ? JSON.parse(params.context) : {};
417
+ const rawContext = params.context === UNKNOWN_TASK_CONTEXT ? undefined : params.context;
418
+ const ctxObj = rawContext ? JSON.parse(rawContext) : {};
400
419
  const obj = typeof ctxObj === "object" && ctxObj !== null && !Array.isArray(ctxObj) ? ctxObj : {};
401
420
  if (inheritedContext) {
402
421
  try {
@@ -430,7 +449,7 @@ function createTaskTool(taskComponent) {
430
449
  due_date: params.due_date,
431
450
  tags: inheritedTags,
432
451
  sessionId,
433
- project_path: inheritedProjectPath ?? params.project_path,
452
+ project_path: inheritedProjectPath ?? (callerProjectPathIsExplicit ? callerProjectPath : UNKNOWN_PROJECT_PATH),
434
453
  context: enrichedContext
435
454
  });
436
455
  setCurrentTaskId(task.id);
@@ -475,9 +494,11 @@ function getTaskTool(taskComponent) {
475
494
  metadata: { execution_time_ms: 0 }
476
495
  };
477
496
  }
497
+ const nested = result.task;
498
+ const flat = nested && typeof nested === "object" ? { ...nested, operations: result.operations } : result;
478
499
  return {
479
500
  success: true,
480
- output: JSON.stringify(result, null, 2),
501
+ output: JSON.stringify(flat, null, 2),
481
502
  metadata: { execution_time_ms: 0 }
482
503
  };
483
504
  } else {