@vibe-lark/larkpal 0.1.86 → 0.1.87

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 (208) hide show
  1. package/dist/account-id-BM1T6029-BzQ_cMoi.mjs +1 -0
  2. package/dist/activation-context--5yu1dPF-XV0Y0pTy.mjs +1 -0
  3. package/dist/anthropic-CFZUCb1w.mjs +39 -0
  4. package/dist/assistant-visible-text-DuFWokAt-BOJV_zwc.mjs +9 -0
  5. package/dist/azure-openai-responses-BEuiMaF-.mjs +1 -0
  6. package/dist/boundary-file-read-BSd9MXPy-gnNVhPKT.mjs +1 -0
  7. package/dist/browser-lifecycle-cleanup-BdNsMhMD-BM97qA_M.mjs +1 -0
  8. package/dist/build-Bkj0hOS2.mjs +3 -0
  9. package/dist/bundled-compat-BpaDaAAu-DJtrIX6i.mjs +27 -0
  10. package/dist/bundled-dir-U738ay4K-BxbzrJOo.mjs +1 -0
  11. package/dist/call-DimWbpgJ-B4pv55RH.mjs +20 -0
  12. package/dist/channel-bootstrap.runtime-BVclcGv1-CEZ0-JP9.mjs +1 -0
  13. package/dist/channel-bootstrap.runtime-Cwcr38m2-Dt6QlQkX.mjs +1 -0
  14. package/dist/chunk-DHbaKqs-.mjs +1 -0
  15. package/dist/cli.mjs +7 -92
  16. package/dist/command-format-LSnUCVVF-Dn4h9IOh.mjs +16 -0
  17. package/dist/config-Bim2pi8a-03N-28sw.mjs +1 -0
  18. package/dist/delivery-context.shared-j5hC5qb1-BSLQG47q.mjs +1 -0
  19. package/dist/diagnostic-ClMwNnUA-BMKvPQJT.mjs +1 -0
  20. package/dist/dist-J5UB83Ws.mjs +601 -0
  21. package/dist/dist-coestTs9.mjs +5 -0
  22. package/dist/env-api-keys-Cuz5irWW.mjs +1 -0
  23. package/dist/event-stream-B7Ei41Bu.mjs +1 -0
  24. package/dist/facade-loader-DFzIYYt_-4bzFvy-b.mjs +1 -0
  25. package/dist/from-Ba69_5cR.mjs +14 -0
  26. package/dist/gateway-method-policy-C7rf0SeV-CTJcMQCE.mjs +1 -0
  27. package/dist/github-copilot-headers-BfhryVuU.mjs +1 -0
  28. package/dist/google-ABo-1guT.mjs +1 -0
  29. package/dist/google-gemini-cli-CGlN1zUA.mjs +2 -0
  30. package/dist/google-shared-C60sNhwd.mjs +301 -0
  31. package/dist/google-vertex-De0nAItu.mjs +1 -0
  32. package/dist/hash-Dw-N8Y9l.mjs +1 -0
  33. package/dist/headers-Bpsp70B9.mjs +1 -0
  34. package/dist/home-dir-C44RaPME-B5iLWwCq.mjs +1 -0
  35. package/dist/ids-BPsM98Uu-CJBJAeVC.mjs +1 -0
  36. package/dist/image-2w3cApg7-CrpUMCvm.mjs +3 -0
  37. package/dist/interactive-init-C5MFL5MW.mjs +8 -0
  38. package/dist/io-CH2g3vsv-JJtUIa_U.mjs +10 -0
  39. package/dist/jiti-loader-cache-Bat69wam-DNIteTtO.mjs +9 -0
  40. package/dist/json-file-BQRNuxmK-hRjIgOXI.mjs +1 -0
  41. package/dist/json-parse-BESd8UAM.mjs +3 -0
  42. package/dist/jws-YaZ38F_i.mjs +12 -0
  43. package/dist/lark-cli-provider-BLMxH6CN.mjs +4 -0
  44. package/dist/lark-logger-xpMKNNtY.mjs +1 -0
  45. package/dist/live-smoke-DpURW676.mjs +33 -0
  46. package/dist/load-context-mb7uvLSn-3xYwSnOZ.mjs +1 -0
  47. package/dist/loader-708jrx4Y-BbJRXNlQ.mjs +4 -0
  48. package/dist/main.mjs +153 -74571
  49. package/dist/manifest-registry-_hxKCS2K-OL8KK_o4.mjs +15 -0
  50. package/dist/mcp-server.mjs +4 -527
  51. package/dist/message-channel-Bk_YHfQg-n2Hw2Y0L.mjs +1 -0
  52. package/dist/message-channel-core-DTA--Gjh-CIh10vfo.mjs +1 -0
  53. package/dist/message.config.runtime-K-k4XOyq-F_h0Cgkl.mjs +1 -0
  54. package/dist/message.gateway.runtime-DqHOHRTQ-ge4c5p4s.mjs +1 -0
  55. package/dist/mistral-DyL3Zo1b.mjs +7 -0
  56. package/dist/model-auth-env-oyg2Hexc-DJbt9J3o.mjs +1 -0
  57. package/dist/models-config-BmpSQJQF-BL6S5qAo.mjs +1 -0
  58. package/dist/models-config.runtime-SOhLEw-f.mjs +1 -0
  59. package/dist/multipart-parser-B9dwXBqu.mjs +2 -0
  60. package/dist/oauth-25y2wc7K.mjs +75 -0
  61. package/dist/openai-C-rgGb7X.mjs +16 -0
  62. package/dist/openai-codex-responses-BbyAPsP1.mjs +7 -0
  63. package/dist/openai-completions-Bu5qvQzb.mjs +5 -0
  64. package/dist/openai-responses-pIdwQBc4.mjs +1 -0
  65. package/dist/openai-responses-shared-DqW1JSux.mjs +10 -0
  66. package/dist/paths-D6msg0S1-BO4XgM1u.mjs +1 -0
  67. package/dist/paths-D92DjaZ--DdtJ-zYp.mjs +1 -0
  68. package/dist/pi-model-discovery-Bd0TWzo8-DvSM0eWu.mjs +1 -0
  69. package/dist/pi-model-discovery-runtime-PrjWOmsV.mjs +1 -0
  70. package/dist/pi-tools.before-tool-call.runtime-Bn7uqKie-WPxU5oNX.mjs +2 -0
  71. package/dist/plugin-auto-enable-DdH3n9V8-Dr_bUXkG.mjs +1 -0
  72. package/dist/process-scoped-map-B2cWkYET-Co-i-MXA.mjs +1 -0
  73. package/dist/provider-discovery.runtime-DY0VWQ81.mjs +1 -0
  74. package/dist/provider-model-compat-CFqcq0it-BUwZENrz.mjs +1 -0
  75. package/dist/provider-runtime-C8rljsNs-BDvu6FW3.mjs +1 -0
  76. package/dist/provider-runtime-CT50mNIX-DImw7ZZu.mjs +79 -0
  77. package/dist/provider-stream-COLujAAo-Dpq1DSIk.mjs +248 -0
  78. package/dist/providers.runtime-Ba7tOlq7-B4t6ywCr.mjs +1 -0
  79. package/dist/public-surface-loader-BVl0NQAE-TfJ3izj1.mjs +1 -0
  80. package/dist/resolve-C33B7eeu-DZM_z6Wr.mjs +1 -0
  81. package/dist/runtime-Cym-fqI8-1GOIuRRQ.mjs +1 -0
  82. package/dist/runtime-channel-state-CohMybAh-BBzhl07Q.mjs +1 -0
  83. package/dist/runtime-snapshot-C54O1-gI-DxusscPf.mjs +1 -0
  84. package/dist/runtime-state-IBOIXKOx-Cw1GA1td.mjs +1 -0
  85. package/dist/runtime-web-tools-fallback.runtime-Ca-qn1mj-BsYE2gOd.mjs +1 -0
  86. package/dist/runtime-web-tools-manifest.runtime-BgxQTjmq-P6MKP9gQ.mjs +1 -0
  87. package/dist/runtime-web-tools-public-artifacts.runtime-D9qcoWIX-5VoyjouO.mjs +1 -0
  88. package/dist/session-archive.runtime-B52_5vs4-cU2tYbBz.mjs +1 -0
  89. package/dist/session-key-Cn2QoOyX-QZeYmbxd.mjs +1 -0
  90. package/dist/session-transcript-files.fs-DEeFXruQ-CXIAFSsr.mjs +1 -0
  91. package/dist/src-CCDx_C-U.mjs +3 -0
  92. package/dist/src-DACmA9V6.mjs +5 -0
  93. package/dist/subagent-announce-L5WsQatW--rMn240x.mjs +2 -0
  94. package/dist/subagent-announce.registry.runtime-DiqZyeTs-DNfNHsls.mjs +1 -0
  95. package/dist/subagent-registry-steer-runtime-DFgZFC0j-XYS1_qwl.mjs +1 -0
  96. package/dist/subagent-system-prompt-C1qnN--K-CsU4f97T.mjs +23 -0
  97. package/dist/target-parsing-loaded-DKkb6jJY-B830OA1a.mjs +12 -0
  98. package/dist/task-registry-delivery-runtime-Dd1CUkZF-B2Hj2k8C.mjs +16 -0
  99. package/dist/task-registry-delivery-runtime-ragbeVx5-Bdvo2Q5u.mjs +1 -0
  100. package/dist/thinking-Bh-7MqXz-uApNUe6g.mjs +1 -0
  101. package/dist/transcript-E_-ISOkD-VTwb782D.mjs +5 -0
  102. package/dist/transcript.runtime-BqhvZZdl-B4E0TiX5.mjs +1 -0
  103. package/dist/transform-messages-BTA3xbAI.mjs +1 -0
  104. package/dist/web-provider-public-artifacts-BlpRwIUS-DbVhDOrY.mjs +1 -0
  105. package/dist/web-search-providers.runtime--0aUtC3b-Bjh4Bmrz.mjs +1 -0
  106. package/package.json +2 -3
  107. package/dist/account-id-BM1T6029-DYjVxojW.mjs +0 -46
  108. package/dist/activation-context--5yu1dPF-Bwsn3moT.mjs +0 -172
  109. package/dist/anthropic-TH8ERTXK.mjs +0 -5962
  110. package/dist/assistant-visible-text-DuFWokAt-CsbII5KS.mjs +0 -596
  111. package/dist/azure-openai-responses-Bt_Ag9Er.mjs +0 -166
  112. package/dist/boundary-file-read-BSd9MXPy--KThL5e6.mjs +0 -594
  113. package/dist/browser-lifecycle-cleanup-BdNsMhMD-O3tnAM4i.mjs +0 -60
  114. package/dist/build-DgTrEpge.mjs +0 -3333
  115. package/dist/bundled-compat-BpaDaAAu-D7oazKjD.mjs +0 -5216
  116. package/dist/bundled-dir-U738ay4K-DXK0q_TV.mjs +0 -258
  117. package/dist/call-DimWbpgJ-ColD4W-y.mjs +0 -9993
  118. package/dist/channel-bootstrap.runtime-BVclcGv1-DJv_Z-Kr.mjs +0 -2
  119. package/dist/channel-bootstrap.runtime-Cwcr38m2-VRfVCR-i.mjs +0 -33
  120. package/dist/chunk-D6SyT4dJ.mjs +0 -36
  121. package/dist/command-format-LSnUCVVF-BQ2SMKka.mjs +0 -685
  122. package/dist/config-Bim2pi8a-BQUdfiEi.mjs +0 -9
  123. package/dist/delivery-context.shared-j5hC5qb1-CI83RXXZ.mjs +0 -72
  124. package/dist/diagnostic-ClMwNnUA-D6nUtLnb.mjs +0 -140
  125. package/dist/dist-CEGw8-2W.mjs +0 -429
  126. package/dist/dist-DD2aJ2UL.mjs +0 -125135
  127. package/dist/env-api-keys-BVvSg7T2.mjs +0 -68
  128. package/dist/event-stream-xaQWmyas.mjs +0 -15226
  129. package/dist/facade-loader-DFzIYYt_-CIr4HKtE.mjs +0 -194
  130. package/dist/from-DF7cl2wz.mjs +0 -3842
  131. package/dist/gateway-method-policy-C7rf0SeV-CJQMEYIE.mjs +0 -28
  132. package/dist/github-copilot-headers-DjqWtUoP.mjs +0 -22
  133. package/dist/google-C2pVrgBZ.mjs +0 -336
  134. package/dist/google-gemini-cli-BBxgS5Ho.mjs +0 -623
  135. package/dist/google-shared-BsWgwEk1.mjs +0 -22791
  136. package/dist/google-vertex-BsVLJrrC.mjs +0 -358
  137. package/dist/hash-DAFtW_W7.mjs +0 -16
  138. package/dist/headers-R3HdCbAE.mjs +0 -8
  139. package/dist/home-dir-C44RaPME-CBRS4HLP.mjs +0 -93
  140. package/dist/ids-BPsM98Uu-CwuxvUai.mjs +0 -77
  141. package/dist/image-2w3cApg7-CxpHvoB5.mjs +0 -207
  142. package/dist/interactive-init-BXQBalNr.mjs +0 -450
  143. package/dist/io-CH2g3vsv-BOGlLlB8.mjs +0 -26218
  144. package/dist/jiti-loader-cache-Bat69wam-D6hCxboy.mjs +0 -5049
  145. package/dist/json-file-BQRNuxmK-DhJM5NsG.mjs +0 -108
  146. package/dist/json-parse-v_HIJjjI.mjs +0 -381
  147. package/dist/jws-GFcTvvVT.mjs +0 -2291
  148. package/dist/lark-cli-provider-BARgbbmo.mjs +0 -554
  149. package/dist/lark-logger-D7_pEVQc.mjs +0 -143
  150. package/dist/live-smoke-BhkBOcH9.mjs +0 -7135
  151. package/dist/load-context-mb7uvLSn-B10MAi3I.mjs +0 -29
  152. package/dist/loader-708jrx4Y-BOswuvpe.mjs +0 -5053
  153. package/dist/manifest-registry-_hxKCS2K-CZdeyN0f.mjs +0 -3512
  154. package/dist/message-channel-Bk_YHfQg-AeNrPPpp.mjs +0 -50
  155. package/dist/message-channel-core-DTA--Gjh-CY4Tkb7N.mjs +0 -29
  156. package/dist/message.config.runtime-K-k4XOyq-DZTmXomP.mjs +0 -2
  157. package/dist/message.gateway.runtime-DqHOHRTQ-DH4ml0YF.mjs +0 -2
  158. package/dist/mistral-CaR4DiLu.mjs +0 -28657
  159. package/dist/model-auth-env-oyg2Hexc-DU_rOUU5.mjs +0 -1306
  160. package/dist/models-config-BmpSQJQF-Gfvh1n3A.mjs +0 -1282
  161. package/dist/models-config.runtime-BsU_22xk.mjs +0 -2
  162. package/dist/multipart-parser-DedmaB5g.mjs +0 -294
  163. package/dist/oauth-DOJeGfcE.mjs +0 -6392
  164. package/dist/openai-BDtIh3Ja.mjs +0 -6693
  165. package/dist/openai-codex-responses-C5EORu31.mjs +0 -664
  166. package/dist/openai-completions-CR_cS6gX.mjs +0 -669
  167. package/dist/openai-responses-oGxwZyuC.mjs +0 -184
  168. package/dist/openai-responses-shared-BixMSDZE.mjs +0 -398
  169. package/dist/paths-D6msg0S1-C2lYuisN.mjs +0 -189
  170. package/dist/paths-D92DjaZ--CTOESW2b.mjs +0 -192
  171. package/dist/pi-model-discovery-Bd0TWzo8-BFsJmeMb.mjs +0 -227
  172. package/dist/pi-model-discovery-runtime-CCCZxkd8.mjs +0 -2
  173. package/dist/pi-tools.before-tool-call.runtime-Bn7uqKie-C5ewk8kK.mjs +0 -399
  174. package/dist/plugin-auto-enable-DdH3n9V8-DsA1isaF.mjs +0 -1456
  175. package/dist/process-scoped-map-B2cWkYET-CXwUZ8CZ.mjs +0 -61
  176. package/dist/provider-discovery.runtime-BPzz1PFj.mjs +0 -58
  177. package/dist/provider-model-compat-CFqcq0it-BDDuBI3A.mjs +0 -118
  178. package/dist/provider-runtime-C8rljsNs-CIT93zoy.mjs +0 -2
  179. package/dist/provider-runtime-CT50mNIX-BwEV6GyO.mjs +0 -573
  180. package/dist/provider-stream-COLujAAo-CbJPDngm.mjs +0 -35449
  181. package/dist/providers.runtime-Ba7tOlq7-CXkhkzU9.mjs +0 -219
  182. package/dist/public-surface-loader-BVl0NQAE-C0piXtsT.mjs +0 -117
  183. package/dist/resolve-C33B7eeu-BNvYTl6k.mjs +0 -1041
  184. package/dist/runtime-Cym-fqI8-DaSDMH-a.mjs +0 -120
  185. package/dist/runtime-channel-state-CohMybAh-hXR6y5Gx.mjs +0 -19
  186. package/dist/runtime-snapshot-C54O1-gI-40cbyi7P.mjs +0 -677
  187. package/dist/runtime-state-IBOIXKOx-Bf9tcLvc.mjs +0 -10
  188. package/dist/runtime-web-tools-fallback.runtime-Ca-qn1mj-BCVImm7a.mjs +0 -39
  189. package/dist/runtime-web-tools-manifest.runtime-BgxQTjmq-Cb4nJkRT.mjs +0 -2
  190. package/dist/runtime-web-tools-public-artifacts.runtime-D9qcoWIX-BrQdXzOQ.mjs +0 -2
  191. package/dist/session-archive.runtime-B52_5vs4-BG-_IwNJ.mjs +0 -2
  192. package/dist/session-key-Cn2QoOyX-CuHbJMgR.mjs +0 -82
  193. package/dist/session-transcript-files.fs-DEeFXruQ-B1PF6nLy.mjs +0 -147
  194. package/dist/src-BgCX0MLG.mjs +0 -813
  195. package/dist/src-DYbqlAqf.mjs +0 -1177
  196. package/dist/subagent-announce-L5WsQatW-CQWI9GMd.mjs +0 -344
  197. package/dist/subagent-announce.registry.runtime-DiqZyeTs-BKuniyi3.mjs +0 -28
  198. package/dist/subagent-registry-steer-runtime-DFgZFC0j-BhBz0roy.mjs +0 -211
  199. package/dist/subagent-system-prompt-C1qnN--K-DpnTFP47.mjs +0 -3061
  200. package/dist/target-parsing-loaded-DKkb6jJY-BMD4CkpS.mjs +0 -1002
  201. package/dist/task-registry-delivery-runtime-Dd1CUkZF-C8U40a3O.mjs +0 -2950
  202. package/dist/task-registry-delivery-runtime-ragbeVx5-CNbFAkjD.mjs +0 -2
  203. package/dist/thinking-Bh-7MqXz-D3woGbO7.mjs +0 -2
  204. package/dist/transcript-E_-ISOkD-DWCfZP2p.mjs +0 -2019
  205. package/dist/transcript.runtime-BqhvZZdl-BPy42vBP.mjs +0 -2
  206. package/dist/transform-messages-DbhIzTxq.mjs +0 -207
  207. package/dist/web-provider-public-artifacts-BlpRwIUS-CGPSV4W2.mjs +0 -295
  208. package/dist/web-search-providers.runtime--0aUtC3b-DyuhC95V.mjs +0 -200
@@ -1,399 +0,0 @@
1
- import { o as isPlainObject } from "./bundled-dir-U738ay4K-DXK0q_TV.mjs";
2
- import { St as createSubsystemLogger } from "./bundled-compat-BpaDaAAu-D7oazKjD.mjs";
3
- import { n as logToolLoopAction, r as getDiagnosticSessionState } from "./diagnostic-ClMwNnUA-D6nUtLnb.mjs";
4
- import { createHash } from "node:crypto";
5
- //#region node_modules/.pnpm/openclaw@2026.4.22_@napi-rs+canvas@0.1.99/node_modules/openclaw/dist/tool-loop-detection-BfqoieyW.js
6
- const log = createSubsystemLogger("agents/loop-detection");
7
- const DEFAULT_LOOP_DETECTION_CONFIG = {
8
- enabled: false,
9
- historySize: 30,
10
- warningThreshold: 10,
11
- unknownToolThreshold: 10,
12
- criticalThreshold: 20,
13
- globalCircuitBreakerThreshold: 30,
14
- detectors: {
15
- genericRepeat: true,
16
- knownPollNoProgress: true,
17
- pingPong: true
18
- }
19
- };
20
- function asPositiveInt(value, fallback) {
21
- if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) return fallback;
22
- return value;
23
- }
24
- function resolveLoopDetectionConfig(config) {
25
- let warningThreshold = asPositiveInt(config?.warningThreshold, DEFAULT_LOOP_DETECTION_CONFIG.warningThreshold);
26
- let criticalThreshold = asPositiveInt(config?.criticalThreshold, DEFAULT_LOOP_DETECTION_CONFIG.criticalThreshold);
27
- let globalCircuitBreakerThreshold = asPositiveInt(config?.globalCircuitBreakerThreshold, DEFAULT_LOOP_DETECTION_CONFIG.globalCircuitBreakerThreshold);
28
- if (criticalThreshold <= warningThreshold) criticalThreshold = warningThreshold + 1;
29
- if (globalCircuitBreakerThreshold <= criticalThreshold) globalCircuitBreakerThreshold = criticalThreshold + 1;
30
- return {
31
- enabled: config?.enabled ?? DEFAULT_LOOP_DETECTION_CONFIG.enabled,
32
- historySize: asPositiveInt(config?.historySize, DEFAULT_LOOP_DETECTION_CONFIG.historySize),
33
- warningThreshold,
34
- unknownToolThreshold: asPositiveInt(config?.unknownToolThreshold, DEFAULT_LOOP_DETECTION_CONFIG.unknownToolThreshold),
35
- criticalThreshold,
36
- globalCircuitBreakerThreshold,
37
- detectors: {
38
- genericRepeat: config?.detectors?.genericRepeat ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.genericRepeat,
39
- knownPollNoProgress: config?.detectors?.knownPollNoProgress ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.knownPollNoProgress,
40
- pingPong: config?.detectors?.pingPong ?? DEFAULT_LOOP_DETECTION_CONFIG.detectors.pingPong
41
- }
42
- };
43
- }
44
- /**
45
- * Hash a tool call for pattern matching.
46
- * Uses tool name + deterministic JSON serialization digest of params.
47
- */
48
- function hashToolCall(toolName, params) {
49
- return `${toolName}:${digestStable(params)}`;
50
- }
51
- function stableStringify(value) {
52
- if (value === null || typeof value !== "object") return JSON.stringify(value);
53
- if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
54
- const obj = value;
55
- return `{${Object.keys(obj).toSorted().map((k) => `${JSON.stringify(k)}:${stableStringify(obj[k])}`).join(",")}}`;
56
- }
57
- function digestStable(value) {
58
- const serialized = stableStringifyFallback(value);
59
- return createHash("sha256").update(serialized).digest("hex");
60
- }
61
- function stableStringifyFallback(value) {
62
- try {
63
- return stableStringify(value);
64
- } catch {
65
- if (value === null || value === void 0) return `${value}`;
66
- if (typeof value === "string") return value;
67
- if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return `${value}`;
68
- if (value instanceof Error) return `${value.name}:${value.message}`;
69
- return Object.prototype.toString.call(value);
70
- }
71
- }
72
- function isKnownPollToolCall(toolName, params) {
73
- if (toolName === "command_status") return true;
74
- if (toolName !== "process" || !isPlainObject(params)) return false;
75
- const action = params.action;
76
- return action === "poll" || action === "log";
77
- }
78
- function extractTextContent(result) {
79
- if (!isPlainObject(result) || !Array.isArray(result.content)) return "";
80
- return result.content.filter((entry) => isPlainObject(entry) && typeof entry.type === "string" && typeof entry.text === "string").map((entry) => entry.text).join("\n").trim();
81
- }
82
- function formatErrorForHash(error) {
83
- if (error instanceof Error) return error.message || error.name;
84
- if (typeof error === "string") return error;
85
- if (typeof error === "number" || typeof error === "boolean" || typeof error === "bigint") return `${error}`;
86
- return stableStringify(error);
87
- }
88
- function extractUnknownToolName(error) {
89
- const raw = formatErrorForHash(error).trim();
90
- if (!raw) return;
91
- const toolName = (raw.match(/unknown tool[:\s]+["']?([a-z0-9_.-]+)["']?/i) ?? raw.match(/tool\s+["']?([a-z0-9_.-]+)["']?\s+(?:not found|is not available)/i))?.[1]?.trim();
92
- return toolName ? toolName.toLowerCase() : void 0;
93
- }
94
- function hashToolOutcome(toolName, params, result, error) {
95
- if (error !== void 0) {
96
- const unknownToolName = extractUnknownToolName(error);
97
- return {
98
- resultHash: `error:${digestStable(formatErrorForHash(error))}`,
99
- unknownToolName
100
- };
101
- }
102
- if (!isPlainObject(result)) return { resultHash: result === void 0 ? void 0 : digestStable(result) };
103
- const details = isPlainObject(result.details) ? result.details : {};
104
- const text = extractTextContent(result);
105
- if (isKnownPollToolCall(toolName, params) && toolName === "process" && isPlainObject(params)) {
106
- const action = params.action;
107
- if (action === "poll") return { resultHash: digestStable({
108
- action,
109
- status: details.status,
110
- exitCode: details.exitCode ?? null,
111
- exitSignal: details.exitSignal ?? null,
112
- aggregated: details.aggregated ?? null,
113
- text
114
- }) };
115
- if (action === "log") return { resultHash: digestStable({
116
- action,
117
- status: details.status,
118
- totalLines: details.totalLines ?? null,
119
- totalChars: details.totalChars ?? null,
120
- truncated: details.truncated ?? null,
121
- exitCode: details.exitCode ?? null,
122
- exitSignal: details.exitSignal ?? null,
123
- text
124
- }) };
125
- }
126
- return { resultHash: digestStable({
127
- details,
128
- text
129
- }) };
130
- }
131
- function getUnknownToolRepeatStreak(history, toolName) {
132
- let streak = 0;
133
- let repeatedUnknownToolName;
134
- for (let i = history.length - 1; i >= 0; i -= 1) {
135
- const record = history[i];
136
- if (!record || record.toolName !== toolName || !record.unknownToolName) break;
137
- if (!repeatedUnknownToolName) {
138
- repeatedUnknownToolName = record.unknownToolName;
139
- streak = 1;
140
- continue;
141
- }
142
- if (record.unknownToolName !== repeatedUnknownToolName) break;
143
- streak += 1;
144
- }
145
- return {
146
- count: streak,
147
- unknownToolName: repeatedUnknownToolName
148
- };
149
- }
150
- function getNoProgressStreak(history, toolName, argsHash) {
151
- let streak = 0;
152
- let latestResultHash;
153
- for (let i = history.length - 1; i >= 0; i -= 1) {
154
- const record = history[i];
155
- if (!record || record.toolName !== toolName || record.argsHash !== argsHash) continue;
156
- if (typeof record.resultHash !== "string" || !record.resultHash) continue;
157
- if (!latestResultHash) {
158
- latestResultHash = record.resultHash;
159
- streak = 1;
160
- continue;
161
- }
162
- if (record.resultHash !== latestResultHash) break;
163
- streak += 1;
164
- }
165
- return {
166
- count: streak,
167
- latestResultHash
168
- };
169
- }
170
- function getPingPongStreak(history, currentSignature) {
171
- const last = history.at(-1);
172
- if (!last) return {
173
- count: 0,
174
- noProgressEvidence: false
175
- };
176
- let otherSignature;
177
- let otherToolName;
178
- for (let i = history.length - 2; i >= 0; i -= 1) {
179
- const call = history[i];
180
- if (!call) continue;
181
- if (call.argsHash !== last.argsHash) {
182
- otherSignature = call.argsHash;
183
- otherToolName = call.toolName;
184
- break;
185
- }
186
- }
187
- if (!otherSignature || !otherToolName) return {
188
- count: 0,
189
- noProgressEvidence: false
190
- };
191
- let alternatingTailCount = 0;
192
- for (let i = history.length - 1; i >= 0; i -= 1) {
193
- const call = history[i];
194
- if (!call) continue;
195
- const expected = alternatingTailCount % 2 === 0 ? last.argsHash : otherSignature;
196
- if (call.argsHash !== expected) break;
197
- alternatingTailCount += 1;
198
- }
199
- if (alternatingTailCount < 2) return {
200
- count: 0,
201
- noProgressEvidence: false
202
- };
203
- if (currentSignature !== otherSignature) return {
204
- count: 0,
205
- noProgressEvidence: false
206
- };
207
- const tailStart = Math.max(0, history.length - alternatingTailCount);
208
- let firstHashA;
209
- let firstHashB;
210
- let noProgressEvidence = true;
211
- for (let i = tailStart; i < history.length; i += 1) {
212
- const call = history[i];
213
- if (!call) continue;
214
- if (!call.resultHash) {
215
- noProgressEvidence = false;
216
- break;
217
- }
218
- if (call.argsHash === last.argsHash) {
219
- if (!firstHashA) firstHashA = call.resultHash;
220
- else if (firstHashA !== call.resultHash) {
221
- noProgressEvidence = false;
222
- break;
223
- }
224
- continue;
225
- }
226
- if (call.argsHash === otherSignature) {
227
- if (!firstHashB) firstHashB = call.resultHash;
228
- else if (firstHashB !== call.resultHash) {
229
- noProgressEvidence = false;
230
- break;
231
- }
232
- continue;
233
- }
234
- noProgressEvidence = false;
235
- break;
236
- }
237
- if (!firstHashA || !firstHashB) noProgressEvidence = false;
238
- return {
239
- count: alternatingTailCount + 1,
240
- pairedToolName: last.toolName,
241
- pairedSignature: last.argsHash,
242
- noProgressEvidence
243
- };
244
- }
245
- function canonicalPairKey(signatureA, signatureB) {
246
- return [signatureA, signatureB].toSorted().join("|");
247
- }
248
- /**
249
- * Detect if an agent is stuck in a repetitive tool call loop.
250
- * Checks if the same tool+params combination has been called excessively.
251
- */
252
- function detectToolCallLoop(state, toolName, params, config) {
253
- const resolvedConfig = resolveLoopDetectionConfig(config);
254
- if (!resolvedConfig.enabled) return { stuck: false };
255
- const history = state.toolCallHistory ?? [];
256
- const currentHash = hashToolCall(toolName, params);
257
- const unknownToolStreak = getUnknownToolRepeatStreak(history, toolName);
258
- const noProgress = getNoProgressStreak(history, toolName, currentHash);
259
- const noProgressStreak = noProgress.count;
260
- const knownPollTool = isKnownPollToolCall(toolName, params);
261
- const pingPong = getPingPongStreak(history, currentHash);
262
- if (unknownToolStreak.count >= resolvedConfig.unknownToolThreshold) return {
263
- stuck: true,
264
- level: "critical",
265
- detector: "unknown_tool_repeat",
266
- count: unknownToolStreak.count,
267
- message: `CRITICAL: attempted unavailable tool ${unknownToolStreak.unknownToolName ?? toolName} ${unknownToolStreak.count} times. Stop retrying that missing tool and answer without it.`,
268
- warningKey: `unknown-tool:${toolName}:${unknownToolStreak.unknownToolName ?? "unknown"}`
269
- };
270
- if (noProgressStreak >= resolvedConfig.globalCircuitBreakerThreshold) {
271
- log.error(`Global circuit breaker triggered: ${toolName} repeated ${noProgressStreak} times with no progress`);
272
- return {
273
- stuck: true,
274
- level: "critical",
275
- detector: "global_circuit_breaker",
276
- count: noProgressStreak,
277
- message: `CRITICAL: ${toolName} has repeated identical no-progress outcomes ${noProgressStreak} times. Session execution blocked by global circuit breaker to prevent runaway loops.`,
278
- warningKey: `global:${toolName}:${currentHash}:${noProgress.latestResultHash ?? "none"}`
279
- };
280
- }
281
- if (knownPollTool && resolvedConfig.detectors.knownPollNoProgress && noProgressStreak >= resolvedConfig.criticalThreshold) {
282
- log.error(`Critical polling loop detected: ${toolName} repeated ${noProgressStreak} times`);
283
- return {
284
- stuck: true,
285
- level: "critical",
286
- detector: "known_poll_no_progress",
287
- count: noProgressStreak,
288
- message: `CRITICAL: Called ${toolName} with identical arguments and no progress ${noProgressStreak} times. This appears to be a stuck polling loop. Session execution blocked to prevent resource waste.`,
289
- warningKey: `poll:${toolName}:${currentHash}:${noProgress.latestResultHash ?? "none"}`
290
- };
291
- }
292
- if (knownPollTool && resolvedConfig.detectors.knownPollNoProgress && noProgressStreak >= resolvedConfig.warningThreshold) {
293
- log.warn(`Polling loop warning: ${toolName} repeated ${noProgressStreak} times`);
294
- return {
295
- stuck: true,
296
- level: "warning",
297
- detector: "known_poll_no_progress",
298
- count: noProgressStreak,
299
- message: `WARNING: You have called ${toolName} ${noProgressStreak} times with identical arguments and no progress. Stop polling and either (1) increase wait time between checks, or (2) report the task as failed if the process is stuck.`,
300
- warningKey: `poll:${toolName}:${currentHash}:${noProgress.latestResultHash ?? "none"}`
301
- };
302
- }
303
- const pingPongWarningKey = pingPong.pairedSignature ? `pingpong:${canonicalPairKey(currentHash, pingPong.pairedSignature)}` : `pingpong:${toolName}:${currentHash}`;
304
- if (resolvedConfig.detectors.pingPong && pingPong.count >= resolvedConfig.criticalThreshold && pingPong.noProgressEvidence) {
305
- log.error(`Critical ping-pong loop detected: alternating calls count=${pingPong.count} currentTool=${toolName}`);
306
- return {
307
- stuck: true,
308
- level: "critical",
309
- detector: "ping_pong",
310
- count: pingPong.count,
311
- message: `CRITICAL: You are alternating between repeated tool-call patterns (${pingPong.count} consecutive calls) with no progress. This appears to be a stuck ping-pong loop. Session execution blocked to prevent resource waste.`,
312
- pairedToolName: pingPong.pairedToolName,
313
- warningKey: pingPongWarningKey
314
- };
315
- }
316
- if (resolvedConfig.detectors.pingPong && pingPong.count >= resolvedConfig.warningThreshold) {
317
- log.warn(`Ping-pong loop warning: alternating calls count=${pingPong.count} currentTool=${toolName}`);
318
- return {
319
- stuck: true,
320
- level: "warning",
321
- detector: "ping_pong",
322
- count: pingPong.count,
323
- message: `WARNING: You are alternating between repeated tool-call patterns (${pingPong.count} consecutive calls). This looks like a ping-pong loop; stop retrying and report the task as failed.`,
324
- pairedToolName: pingPong.pairedToolName,
325
- warningKey: pingPongWarningKey
326
- };
327
- }
328
- const recentCount = history.filter((h) => h.toolName === toolName && h.argsHash === currentHash).length;
329
- if (!knownPollTool && resolvedConfig.detectors.genericRepeat && recentCount >= resolvedConfig.warningThreshold) {
330
- log.warn(`Loop warning: ${toolName} called ${recentCount} times with identical arguments`);
331
- return {
332
- stuck: true,
333
- level: "warning",
334
- detector: "generic_repeat",
335
- count: recentCount,
336
- message: `WARNING: You have called ${toolName} ${recentCount} times with identical arguments. If this is not making progress, stop retrying and report the task as failed.`,
337
- warningKey: `generic:${toolName}:${currentHash}`
338
- };
339
- }
340
- return { stuck: false };
341
- }
342
- /**
343
- * Record a tool call in the session's history for loop detection.
344
- * Maintains sliding window of last N calls.
345
- */
346
- function recordToolCall(state, toolName, params, toolCallId, config) {
347
- const resolvedConfig = resolveLoopDetectionConfig(config);
348
- if (!state.toolCallHistory) state.toolCallHistory = [];
349
- state.toolCallHistory.push({
350
- toolName,
351
- argsHash: hashToolCall(toolName, params),
352
- toolCallId,
353
- timestamp: Date.now()
354
- });
355
- if (state.toolCallHistory.length > resolvedConfig.historySize) state.toolCallHistory.shift();
356
- }
357
- /**
358
- * Record a completed tool call outcome so loop detection can identify no-progress repeats.
359
- */
360
- function recordToolCallOutcome(state, params) {
361
- const resolvedConfig = resolveLoopDetectionConfig(params.config);
362
- const outcome = hashToolOutcome(params.toolName, params.toolParams, params.result, params.error);
363
- const resultHash = outcome.resultHash;
364
- if (!resultHash) return;
365
- if (!state.toolCallHistory) state.toolCallHistory = [];
366
- const argsHash = hashToolCall(params.toolName, params.toolParams);
367
- let matched = false;
368
- for (let i = state.toolCallHistory.length - 1; i >= 0; i -= 1) {
369
- const call = state.toolCallHistory[i];
370
- if (!call) continue;
371
- if (params.toolCallId && call.toolCallId !== params.toolCallId) continue;
372
- if (call.toolName !== params.toolName || call.argsHash !== argsHash) continue;
373
- if (call.resultHash !== void 0) continue;
374
- call.resultHash = resultHash;
375
- call.unknownToolName = outcome.unknownToolName;
376
- matched = true;
377
- break;
378
- }
379
- if (!matched) state.toolCallHistory.push({
380
- toolName: params.toolName,
381
- argsHash,
382
- toolCallId: params.toolCallId,
383
- resultHash,
384
- unknownToolName: outcome.unknownToolName,
385
- timestamp: Date.now()
386
- });
387
- if (state.toolCallHistory.length > resolvedConfig.historySize) state.toolCallHistory.splice(0, state.toolCallHistory.length - resolvedConfig.historySize);
388
- }
389
- //#endregion
390
- //#region node_modules/.pnpm/openclaw@2026.4.22_@napi-rs+canvas@0.1.99/node_modules/openclaw/dist/pi-tools.before-tool-call.runtime-Bn7uqKie.js
391
- const beforeToolCallRuntime = {
392
- getDiagnosticSessionState,
393
- logToolLoopAction,
394
- detectToolCallLoop,
395
- recordToolCall,
396
- recordToolCallOutcome
397
- };
398
- //#endregion
399
- export { beforeToolCallRuntime };