@elizaos/plugin-steward-app 2.0.3-beta.6 → 2.0.3-beta.7

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 (219) hide show
  1. package/dist/ApprovalQueue.d.ts +18 -0
  2. package/dist/ApprovalQueue.d.ts.map +1 -0
  3. package/dist/ApprovalQueue.js +420 -0
  4. package/dist/ApprovalQueue.js.map +1 -0
  5. package/dist/StewardLogo.d.ts +11 -0
  6. package/dist/StewardLogo.d.ts.map +1 -0
  7. package/dist/StewardLogo.js +36 -0
  8. package/dist/StewardLogo.js.map +1 -0
  9. package/dist/StewardView.d.ts +13 -0
  10. package/dist/StewardView.d.ts.map +1 -0
  11. package/dist/StewardView.helpers.d.ts +15 -0
  12. package/dist/StewardView.helpers.d.ts.map +1 -0
  13. package/dist/StewardView.helpers.js +45 -0
  14. package/dist/StewardView.helpers.js.map +1 -0
  15. package/dist/StewardView.interact.d.ts +2 -0
  16. package/dist/StewardView.interact.d.ts.map +1 -0
  17. package/dist/StewardView.interact.js +54 -0
  18. package/dist/StewardView.interact.js.map +1 -0
  19. package/dist/StewardView.js +249 -0
  20. package/dist/StewardView.js.map +1 -0
  21. package/dist/TransactionHistory.d.ts +22 -0
  22. package/dist/TransactionHistory.d.ts.map +1 -0
  23. package/dist/TransactionHistory.js +361 -0
  24. package/dist/TransactionHistory.js.map +1 -0
  25. package/dist/__fixtures__/steward-sdk-fixtures.d.ts +10 -0
  26. package/dist/__fixtures__/steward-sdk-fixtures.d.ts.map +1 -0
  27. package/dist/__fixtures__/steward-sdk-fixtures.js +60 -0
  28. package/dist/__fixtures__/steward-sdk-fixtures.js.map +1 -0
  29. package/dist/actions/wallet-action-shared.d.ts +15 -0
  30. package/dist/actions/wallet-action-shared.d.ts.map +1 -0
  31. package/dist/actions/wallet-action-shared.js +16 -0
  32. package/dist/actions/wallet-action-shared.js.map +1 -0
  33. package/dist/api/binance-skill-helpers.d.ts +21 -0
  34. package/dist/api/binance-skill-helpers.d.ts.map +1 -0
  35. package/dist/api/binance-skill-helpers.js +790 -0
  36. package/dist/api/binance-skill-helpers.js.map +1 -0
  37. package/dist/api/bsc-trade.d.ts +36 -0
  38. package/dist/api/bsc-trade.d.ts.map +1 -0
  39. package/dist/api/bsc-trade.js +796 -0
  40. package/dist/api/bsc-trade.js.map +1 -0
  41. package/dist/api/trade-safety.d.ts +35 -0
  42. package/dist/api/trade-safety.d.ts.map +1 -0
  43. package/dist/api/trade-safety.js +56 -0
  44. package/dist/api/trade-safety.js.map +1 -0
  45. package/dist/api/tx-service.d.ts +53 -0
  46. package/dist/api/tx-service.d.ts.map +1 -0
  47. package/dist/api/tx-service.js +206 -0
  48. package/dist/api/tx-service.js.map +1 -0
  49. package/dist/api/wallet-bsc-routes.d.ts +63 -0
  50. package/dist/api/wallet-bsc-routes.d.ts.map +1 -0
  51. package/dist/api/wallet-bsc-routes.js +337 -0
  52. package/dist/api/wallet-bsc-routes.js.map +1 -0
  53. package/dist/api/wallet-capability.d.ts +2 -0
  54. package/dist/api/wallet-capability.d.ts.map +1 -0
  55. package/dist/api/wallet-capability.js +15 -0
  56. package/dist/api/wallet-capability.js.map +1 -0
  57. package/dist/api/wallet-dex-prices.d.ts +43 -0
  58. package/dist/api/wallet-dex-prices.d.ts.map +1 -0
  59. package/dist/api/wallet-dex-prices.js +132 -0
  60. package/dist/api/wallet-dex-prices.js.map +1 -0
  61. package/dist/api/wallet-evm-balance.d.ts +72 -0
  62. package/dist/api/wallet-evm-balance.d.ts.map +1 -0
  63. package/dist/api/wallet-evm-balance.js +697 -0
  64. package/dist/api/wallet-evm-balance.js.map +1 -0
  65. package/dist/api/wallet-routes.d.ts +27 -0
  66. package/dist/api/wallet-routes.d.ts.map +1 -0
  67. package/dist/api/wallet-routes.js +556 -0
  68. package/dist/api/wallet-routes.js.map +1 -0
  69. package/dist/api/wallet-rpc.d.ts +73 -0
  70. package/dist/api/wallet-rpc.d.ts.map +1 -0
  71. package/dist/api/wallet-rpc.js +460 -0
  72. package/dist/api/wallet-rpc.js.map +1 -0
  73. package/dist/api/wallet-trade-routes.d.ts +104 -0
  74. package/dist/api/wallet-trade-routes.d.ts.map +1 -0
  75. package/dist/api/wallet-trade-routes.js +353 -0
  76. package/dist/api/wallet-trade-routes.js.map +1 -0
  77. package/dist/api/wallet-trading-profile.d.ts +31 -0
  78. package/dist/api/wallet-trading-profile.d.ts.map +1 -0
  79. package/dist/api/wallet-trading-profile.js +500 -0
  80. package/dist/api/wallet-trading-profile.js.map +1 -0
  81. package/dist/api/wallet.d.ts +60 -0
  82. package/dist/api/wallet.d.ts.map +1 -0
  83. package/dist/api/wallet.js +617 -0
  84. package/dist/api/wallet.js.map +1 -0
  85. package/dist/chain-utils.d.ts +10 -0
  86. package/dist/chain-utils.d.ts.map +1 -0
  87. package/dist/chain-utils.js +81 -0
  88. package/dist/chain-utils.js.map +1 -0
  89. package/dist/components/StewardSpatialView.d.ts +74 -0
  90. package/dist/components/StewardSpatialView.d.ts.map +1 -0
  91. package/dist/components/StewardSpatialView.js +309 -0
  92. package/dist/components/StewardSpatialView.js.map +1 -0
  93. package/dist/index.d.ts +20 -0
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +77 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/plugin.d.ts +21 -0
  98. package/dist/plugin.d.ts.map +1 -0
  99. package/dist/plugin.js +319 -0
  100. package/dist/plugin.js.map +1 -0
  101. package/dist/providers/steward-balance.d.ts +12 -0
  102. package/dist/providers/steward-balance.d.ts.map +1 -0
  103. package/dist/providers/steward-balance.js +85 -0
  104. package/dist/providers/steward-balance.js.map +1 -0
  105. package/dist/providers/steward-receive-address.d.ts +12 -0
  106. package/dist/providers/steward-receive-address.d.ts.map +1 -0
  107. package/dist/providers/steward-receive-address.js +47 -0
  108. package/dist/providers/steward-receive-address.js.map +1 -0
  109. package/dist/register-routes.d.ts +2 -0
  110. package/dist/register-routes.d.ts.map +1 -0
  111. package/dist/register-routes.js +6 -0
  112. package/dist/register-routes.js.map +1 -0
  113. package/dist/register-terminal-view.d.ts +15 -0
  114. package/dist/register-terminal-view.d.ts.map +1 -0
  115. package/dist/register-terminal-view.js +34 -0
  116. package/dist/register-terminal-view.js.map +1 -0
  117. package/dist/routes/steward-bridge.d.ts +202 -0
  118. package/dist/routes/steward-bridge.d.ts.map +1 -0
  119. package/dist/routes/steward-bridge.js +776 -0
  120. package/dist/routes/steward-bridge.js.map +1 -0
  121. package/dist/routes/steward-compat-routes.d.ts +21 -0
  122. package/dist/routes/steward-compat-routes.d.ts.map +1 -0
  123. package/dist/routes/steward-compat-routes.js +350 -0
  124. package/dist/routes/steward-compat-routes.js.map +1 -0
  125. package/dist/routes/wallet-browser-compat-routes.d.ts +6 -0
  126. package/dist/routes/wallet-browser-compat-routes.d.ts.map +1 -0
  127. package/dist/routes/wallet-browser-compat-routes.js +402 -0
  128. package/dist/routes/wallet-browser-compat-routes.js.map +1 -0
  129. package/dist/routes/wallet-bsc-core-routes.d.ts +15 -0
  130. package/dist/routes/wallet-bsc-core-routes.d.ts.map +1 -0
  131. package/dist/routes/wallet-bsc-core-routes.js +59 -0
  132. package/dist/routes/wallet-bsc-core-routes.js.map +1 -0
  133. package/dist/routes/wallet-compat-routes.d.ts +13 -0
  134. package/dist/routes/wallet-compat-routes.d.ts.map +1 -0
  135. package/dist/routes/wallet-compat-routes.js +206 -0
  136. package/dist/routes/wallet-compat-routes.js.map +1 -0
  137. package/dist/routes/wallet-core-routes.d.ts +16 -0
  138. package/dist/routes/wallet-core-routes.d.ts.map +1 -0
  139. package/dist/routes/wallet-core-routes.js +48 -0
  140. package/dist/routes/wallet-core-routes.js.map +1 -0
  141. package/dist/routes/wallet-trade-compat-routes.d.ts +11 -0
  142. package/dist/routes/wallet-trade-compat-routes.d.ts.map +1 -0
  143. package/dist/routes/wallet-trade-compat-routes.js +570 -0
  144. package/dist/routes/wallet-trade-compat-routes.js.map +1 -0
  145. package/dist/security/hydrate-wallet-keys-from-platform-store.d.ts +7 -0
  146. package/dist/security/hydrate-wallet-keys-from-platform-store.d.ts.map +1 -0
  147. package/dist/security/hydrate-wallet-keys-from-platform-store.js +43 -0
  148. package/dist/security/hydrate-wallet-keys-from-platform-store.js.map +1 -0
  149. package/dist/security/wallet-os-store-actions.d.ts +14 -0
  150. package/dist/security/wallet-os-store-actions.d.ts.map +1 -0
  151. package/dist/security/wallet-os-store-actions.js +63 -0
  152. package/dist/security/wallet-os-store-actions.js.map +1 -0
  153. package/dist/services/steward-credentials.d.ts +2 -0
  154. package/dist/services/steward-credentials.d.ts.map +1 -0
  155. package/dist/services/steward-credentials.js +2 -0
  156. package/dist/services/steward-credentials.js.map +1 -0
  157. package/dist/services/steward-evm-account.d.ts +75 -0
  158. package/dist/services/steward-evm-account.d.ts.map +1 -0
  159. package/dist/services/steward-evm-account.js +279 -0
  160. package/dist/services/steward-evm-account.js.map +1 -0
  161. package/dist/services/steward-evm-bridge.d.ts +36 -0
  162. package/dist/services/steward-evm-bridge.d.ts.map +1 -0
  163. package/dist/services/steward-evm-bridge.js +78 -0
  164. package/dist/services/steward-evm-bridge.js.map +1 -0
  165. package/dist/services/steward-sidecar/health-check.d.ts +2 -0
  166. package/dist/services/steward-sidecar/health-check.d.ts.map +1 -0
  167. package/dist/services/steward-sidecar/health-check.js +2 -0
  168. package/dist/services/steward-sidecar/health-check.js.map +1 -0
  169. package/dist/services/steward-sidecar/helpers.d.ts +2 -0
  170. package/dist/services/steward-sidecar/helpers.d.ts.map +1 -0
  171. package/dist/services/steward-sidecar/helpers.js +2 -0
  172. package/dist/services/steward-sidecar/helpers.js.map +1 -0
  173. package/dist/services/steward-sidecar/process-management.d.ts +2 -0
  174. package/dist/services/steward-sidecar/process-management.d.ts.map +1 -0
  175. package/dist/services/steward-sidecar/process-management.js +2 -0
  176. package/dist/services/steward-sidecar/process-management.js.map +1 -0
  177. package/dist/services/steward-sidecar/types.d.ts +2 -0
  178. package/dist/services/steward-sidecar/types.d.ts.map +1 -0
  179. package/dist/services/steward-sidecar/types.js +2 -0
  180. package/dist/services/steward-sidecar/types.js.map +1 -0
  181. package/dist/services/steward-sidecar/wallet-setup.d.ts +2 -0
  182. package/dist/services/steward-sidecar/wallet-setup.d.ts.map +1 -0
  183. package/dist/services/steward-sidecar/wallet-setup.js +2 -0
  184. package/dist/services/steward-sidecar/wallet-setup.js.map +1 -0
  185. package/dist/services/steward-sidecar.d.ts +2 -0
  186. package/dist/services/steward-sidecar.d.ts.map +1 -0
  187. package/dist/services/steward-sidecar.js +2 -0
  188. package/dist/services/steward-sidecar.js.map +1 -0
  189. package/dist/services/steward-wallet.d.ts +25 -0
  190. package/dist/services/steward-wallet.d.ts.map +1 -0
  191. package/dist/services/steward-wallet.js +333 -0
  192. package/dist/services/steward-wallet.js.map +1 -0
  193. package/dist/steward-ui-state.d.ts +14 -0
  194. package/dist/steward-ui-state.d.ts.map +1 -0
  195. package/dist/steward-ui-state.js +46 -0
  196. package/dist/steward-ui-state.js.map +1 -0
  197. package/dist/steward-view-bundle.d.ts +3 -0
  198. package/dist/steward-view-bundle.d.ts.map +1 -0
  199. package/dist/steward-view-bundle.js +7 -0
  200. package/dist/steward-view-bundle.js.map +1 -0
  201. package/dist/types/bsc-trade.d.ts +180 -0
  202. package/dist/types/bsc-trade.d.ts.map +1 -0
  203. package/dist/types/bsc-trade.js +1 -0
  204. package/dist/types/bsc-trade.js.map +1 -0
  205. package/dist/types/index.d.ts +3 -0
  206. package/dist/types/index.d.ts.map +1 -0
  207. package/dist/types/index.js +3 -0
  208. package/dist/types/index.js.map +1 -0
  209. package/dist/types/steward.d.ts +83 -0
  210. package/dist/types/steward.d.ts.map +1 -0
  211. package/dist/types/steward.js +1 -0
  212. package/dist/types/steward.js.map +1 -0
  213. package/dist/ui.d.ts +7 -0
  214. package/dist/ui.d.ts.map +1 -0
  215. package/dist/ui.js +7 -0
  216. package/dist/ui.js.map +1 -0
  217. package/dist/views/bundle.js +601 -0
  218. package/dist/views/bundle.js.map +1 -0
  219. package/package.json +8 -8
@@ -0,0 +1,790 @@
1
+ import { extractCompatTextContent } from "@elizaos/agent";
2
+ import {
3
+ ModelType
4
+ } from "@elizaos/core";
5
+ const EXPOSED_BINANCE_SKILL_IDS = /* @__PURE__ */ new Set([
6
+ "binance-crypto-market-rank",
7
+ "binance-meme-rush",
8
+ "binance-query-address-info",
9
+ "binance-query-token-audit",
10
+ "binance-query-token-info",
11
+ "binance-trading-signal"
12
+ ]);
13
+ function shouldExposeBinanceSkillId(skillId) {
14
+ const normalized = skillId.trim();
15
+ if (!normalized.startsWith("binance-")) return true;
16
+ return EXPOSED_BINANCE_SKILL_IDS.has(normalized);
17
+ }
18
+ async function rewriteFallbackActionText(args) {
19
+ const text = args.text.trim();
20
+ if (!text) return args.text;
21
+ const fallback = () => {
22
+ const error = typeof args.content?.error === "string" && args.content.error.trim() ? ` It reported: ${args.content.error.trim()}` : "";
23
+ return `I ran ${args.actionName} and got a result, but I couldn't format the details cleanly here.${error}`;
24
+ };
25
+ if (typeof args.runtime.useModel !== "function") return fallback();
26
+ try {
27
+ const raw = await args.runtime.useModel(ModelType.TEXT_SMALL, {
28
+ prompt: [
29
+ "Rewrite this fallback action output in the assistant character's user-facing voice.",
30
+ 'Return strict JSON only: {"response":"..."}.',
31
+ "",
32
+ "Rules:",
33
+ "- Preserve status, IDs, names, URLs, counts, errors, warnings, and next steps.",
34
+ "- Do not expose raw JSON, shell output, schema names, stack traces, or internal action plumbing unless an exact value is necessary.",
35
+ "- Do not claim success if the payload says failed or pending.",
36
+ "- Keep it brief and natural.",
37
+ "",
38
+ `Character: ${JSON.stringify({
39
+ name: args.runtime.character?.name,
40
+ system: args.runtime.character?.system,
41
+ bio: args.runtime.character?.bio,
42
+ style: args.runtime.character?.style
43
+ })}`,
44
+ `Action: ${JSON.stringify(args.actionName)}`,
45
+ `Payload: ${JSON.stringify(text)}`,
46
+ `Metadata: ${JSON.stringify({
47
+ source: args.content?.source,
48
+ actions: args.content?.actions,
49
+ actionStatus: args.content?.actionStatus,
50
+ error: args.content?.error
51
+ })}`
52
+ ].join("\n"),
53
+ maxTokens: 260,
54
+ providerOptions: { eliza: { thinking: "off" } }
55
+ });
56
+ const parsed = JSON.parse(String(raw).trim());
57
+ return typeof parsed.response === "string" && parsed.response.trim() ? parsed.response.trim() : fallback();
58
+ } catch (err) {
59
+ args.runtime.logger?.debug?.(
60
+ {
61
+ src: "eliza-api",
62
+ action: args.actionName,
63
+ err: err instanceof Error ? err.message : String(err)
64
+ },
65
+ "[eliza-api] Fallback action voice rewrite failed"
66
+ );
67
+ return fallback();
68
+ }
69
+ }
70
+ let ownerBlockFallbackPromise = null;
71
+ async function resolveBuiltInFallbackAction(actionName) {
72
+ if (actionName !== "BLOCK") {
73
+ return null;
74
+ }
75
+ if (!ownerBlockFallbackPromise) {
76
+ ownerBlockFallbackPromise = import("@elizaos/plugin-personal-assistant").then((mod) => mod.websiteBlockAction ?? null).catch(() => null);
77
+ }
78
+ return ownerBlockFallbackPromise;
79
+ }
80
+ function inferBalanceChainFromText(input) {
81
+ const normalized = input.toLowerCase();
82
+ if (/\bsol(?:ana)?\b/.test(normalized)) return "solana";
83
+ if (/\b(bsc|bnb|binance)\b/.test(normalized)) return "bsc";
84
+ if (/\bbase\b/.test(normalized)) return "base";
85
+ if (/\b(eth|ethereum)\b/.test(normalized)) return "ethereum";
86
+ return "all";
87
+ }
88
+ function shouldForceCheckBalanceFallback(parsedActions, userText, responseText) {
89
+ const nonReplyActions = parsedActions.filter(
90
+ (a) => a.name !== "REPLY" && a.name !== "NONE" && a.name !== "IGNORE"
91
+ );
92
+ if (nonReplyActions.length > 0) return false;
93
+ const combined = `${userText}
94
+ ${responseText}`.toLowerCase();
95
+ const balanceIntent = /\b(balance|wallet|holdings|portfolio|funds|how much)\b/.test(combined) || /\b(check(ing)?|look(ing)? up|fetch(ing)?)\b/.test(combined);
96
+ return balanceIntent;
97
+ }
98
+ function isBalanceIntent(input) {
99
+ const normalized = input.toLowerCase();
100
+ return /\b(balance|wallet|holdings|portfolio|funds|how much)\b/.test(
101
+ normalized
102
+ );
103
+ }
104
+ function parseFallbackActionBlocks(value, _responseText) {
105
+ const rawValues = [];
106
+ if (typeof value === "string") {
107
+ rawValues.push(value);
108
+ } else if (Array.isArray(value)) {
109
+ for (const entry of value) {
110
+ if (typeof entry === "string" && entry.trim().length > 0) {
111
+ rawValues.push(entry);
112
+ }
113
+ }
114
+ }
115
+ const parsed = [];
116
+ for (const raw of rawValues) {
117
+ const normalized = raw.trim().toUpperCase();
118
+ if (/^[A-Z0-9_]+$/.test(normalized)) {
119
+ parsed.push({ name: normalized, parameters: {} });
120
+ }
121
+ }
122
+ return parsed;
123
+ }
124
+ async function executeFallbackParsedActions(runtime, message, parsedActions, appendIncomingText, onActionCallback, options) {
125
+ const runtimeActions = Array.isArray(
126
+ runtime.actions
127
+ ) ? runtime.actions : [];
128
+ const lookup = /* @__PURE__ */ new Map();
129
+ for (const action of runtimeActions) {
130
+ if (typeof action.name === "string")
131
+ lookup.set(action.name.toUpperCase(), action);
132
+ if (!Array.isArray(action.similes)) continue;
133
+ for (const alias of action.similes) {
134
+ if (typeof alias === "string") lookup.set(alias.toUpperCase(), action);
135
+ }
136
+ }
137
+ for (const parsed of parsedActions) {
138
+ if (parsed.name === "REPLY" || parsed.name === "NONE" || parsed.name === "IGNORE") {
139
+ continue;
140
+ }
141
+ const action = lookup.get(parsed.name) ?? await resolveBuiltInFallbackAction(parsed.name);
142
+ if (!action || typeof action.handler !== "function") continue;
143
+ if (typeof action.validate === "function") {
144
+ const valid = await Promise.resolve(
145
+ action.validate(runtime, message, void 0)
146
+ );
147
+ if (!valid) continue;
148
+ }
149
+ let callbackSeen = false;
150
+ const actionResult = await Promise.resolve(
151
+ action.handler(
152
+ runtime,
153
+ message,
154
+ void 0,
155
+ { parameters: parsed.parameters ?? {} },
156
+ async (content) => {
157
+ const contentRecord = content && typeof content === "object" ? content : {};
158
+ const actionTag = typeof contentRecord.action === "string" ? contentRecord.action : parsed.name;
159
+ const chunk = contentRecord && typeof contentRecord === "object" ? extractCompatTextContent(contentRecord) : "";
160
+ callbackSeen = true;
161
+ onActionCallback(actionTag, Boolean(chunk));
162
+ if (chunk) {
163
+ const voicedChunk = await rewriteFallbackActionText({
164
+ runtime,
165
+ actionName: actionTag,
166
+ text: chunk,
167
+ content: contentRecord
168
+ });
169
+ (options?.onCallbackText ?? appendIncomingText)(voicedChunk);
170
+ }
171
+ return [];
172
+ },
173
+ []
174
+ )
175
+ );
176
+ if (!callbackSeen) {
177
+ const currentText = options?.getCurrentText?.() ?? "";
178
+ const actionSucceeded = actionResult && typeof actionResult === "object" && "success" in actionResult ? actionResult.success === true : void 0;
179
+ const fallbackText = actionResult && typeof actionResult === "object" ? typeof actionResult.text === "string" ? actionResult.text : "" : "";
180
+ const shouldSuppressSuccessFallbackText = parsed.name === "BLOCK" && actionSucceeded === true && /\b(block|blocking|self ?control)\b/i.test(currentText);
181
+ if (fallbackText) {
182
+ onActionCallback(parsed.name, !shouldSuppressSuccessFallbackText);
183
+ if (!shouldSuppressSuccessFallbackText) {
184
+ const voicedFallbackText = await rewriteFallbackActionText({
185
+ runtime,
186
+ actionName: parsed.name,
187
+ text: fallbackText
188
+ });
189
+ appendIncomingText(
190
+ currentText.trim().length > 0 ? `
191
+
192
+ ${voicedFallbackText}` : voicedFallbackText
193
+ );
194
+ }
195
+ }
196
+ }
197
+ }
198
+ }
199
+ const BINANCE_SKILL_KEYWORD_MAP = [
200
+ // meme-rush: meme tokens, pump.fun, bonding curve, launchpad tokens
201
+ {
202
+ pattern: /\b(?:meme\s*(?:token|coin|rush)?|pump\.?fun|four\.?meme|bonding\s*curve|launchpad\s*token|new\s*(?:token|coin)s?\s*on|trending\s*(?:token|coin))/i,
203
+ slug: "binance-meme-rush"
204
+ },
205
+ // trading-signal: smart money signals, whale signals
206
+ {
207
+ pattern: /\b(?:(?:trading|smart\s*money|whale)\s*signal|signal\s*(?:list|data))/i,
208
+ slug: "binance-trading-signal"
209
+ },
210
+ // crypto-market-rank: market rankings, trending, alpha, leaderboard
211
+ {
212
+ pattern: /\b(?:(?:market|crypto)\s*rank|leader\s*board|top\s*(?:trader|search|token)|alpha\s*(?:token|rank)|smart\s*money\s*(?:rank|inflow))/i,
213
+ slug: "binance-crypto-market-rank"
214
+ },
215
+ // query-token-audit: token/contract audit, rug check, security scan
216
+ {
217
+ pattern: /\b(?:(?:token|contract)\s*audit|audit\s*(?:this\s*)?(?:token|contract)|(?:rug|security|safety)\s*(?:check|scan)|check\s*(?:this\s*)?contract)/i,
218
+ slug: "binance-query-token-audit"
219
+ },
220
+ // query-token-info: token info, token price, token detail, search token
221
+ {
222
+ pattern: /\b(?:(?:token|coin)\s*(?:info|detail|price|data|search)|search\s*(?:token|coin)|look\s*up\s*(?:token|coin))/i,
223
+ slug: "binance-query-token-info"
224
+ },
225
+ // query-address-info: wallet balance, address info, check wallet
226
+ {
227
+ pattern: /\b(?:(?:wallet|address)\s*(?:balance|info|detail|holding)|check\s*(?:this\s*)?(?:wallet|address)|(?:wallet|address)\s*check)/i,
228
+ slug: "binance-query-address-info"
229
+ }
230
+ ];
231
+ function extractDirectBinanceSkillSlug(userText) {
232
+ const normalized = userText.toLowerCase();
233
+ const skillMatch = normalized.match(/\b(binance-[a-z0-9-]+)\b/);
234
+ if (skillMatch) {
235
+ if (/\b(use|run|show|fetch|pull|get)\b/.test(normalized)) {
236
+ return skillMatch[1];
237
+ }
238
+ }
239
+ for (const { pattern, slug } of BINANCE_SKILL_KEYWORD_MAP) {
240
+ if (pattern.test(normalized)) {
241
+ return slug;
242
+ }
243
+ }
244
+ return null;
245
+ }
246
+ function pickDirectBinanceLimit(userText, fallback, max) {
247
+ const matches = userText.match(/\b([1-9]\d{0,2})\b/g);
248
+ if (!matches) return String(fallback);
249
+ for (const raw of matches) {
250
+ const value = Number(raw);
251
+ if (value >= 1 && value <= max) {
252
+ return String(value);
253
+ }
254
+ }
255
+ return String(fallback);
256
+ }
257
+ function extractExplicitDirectBinanceCount(userText, max) {
258
+ const matches = userText.match(/\b([1-9]\d{0,2})\b/g);
259
+ if (!matches) return null;
260
+ for (const raw of matches) {
261
+ const value = Number(raw);
262
+ if (value >= 1 && value <= max) {
263
+ return value;
264
+ }
265
+ }
266
+ return null;
267
+ }
268
+ function pickDirectBinanceChain(userText, allowed, fallback) {
269
+ const normalized = userText.toLowerCase();
270
+ const candidates = [
271
+ ["solana", /\bsolana\b|\bsol\b|pump\.fun/],
272
+ ["bsc", /\bbsc\b|\bbnb\b|four\.meme/],
273
+ ["base", /\bbase\b/],
274
+ ["eth", /\beth\b|\bethereum\b/]
275
+ ];
276
+ for (const [chain, pattern] of candidates) {
277
+ if (allowed.includes(chain) && pattern.test(normalized)) {
278
+ return chain;
279
+ }
280
+ }
281
+ return fallback;
282
+ }
283
+ function resolveDirectBinanceMemeRushCommand(userText) {
284
+ const normalized = userText.toLowerCase();
285
+ const chain = pickDirectBinanceChain(normalized, ["solana", "bsc"], "solana");
286
+ if (/topic|topics|narrative|narratives|social rush|hot topic|hot topics/.test(
287
+ normalized
288
+ )) {
289
+ const type = /rising|inflow/.test(normalized) ? "rising" : "latest";
290
+ const sort = /inflow/.test(normalized) ? "inflow" : "time";
291
+ const explicitCount = extractExplicitDirectBinanceCount(normalized, 50);
292
+ return {
293
+ script: "fetch-topics.sh",
294
+ args: explicitCount ? [chain, type, sort, String(explicitCount)] : [chain, type, sort]
295
+ };
296
+ }
297
+ const stage = /migrat/.test(normalized) ? "migrated" : /finaliz|about to migrate/.test(normalized) ? "finalizing" : "new";
298
+ const limit = pickDirectBinanceLimit(normalized, 20, 200);
299
+ return { script: "fetch-trending.sh", args: [chain, stage, limit] };
300
+ }
301
+ function extractQuotedUserText(userText) {
302
+ const quotedMatch = userText.match(/["'`“”]([^"'`“”]{2,120})["'`“”]/);
303
+ return quotedMatch?.[1]?.trim() || null;
304
+ }
305
+ function extractFirstEvmAddress(userText) {
306
+ return userText.match(/\b0x[a-fA-F0-9]{40}\b/)?.[0] ?? null;
307
+ }
308
+ function extractFirstSolanaAddress(userText) {
309
+ const candidates = userText.match(/\b[1-9A-HJ-NP-Za-km-z]{32,44}\b/g) ?? [];
310
+ for (const candidate of candidates) {
311
+ if (candidate.toLowerCase().startsWith("binance") || candidate.toLowerCase().startsWith("signal")) {
312
+ continue;
313
+ }
314
+ return candidate;
315
+ }
316
+ return null;
317
+ }
318
+ function extractDirectBinanceSearchKeyword(userText) {
319
+ const quoted = extractQuotedUserText(userText);
320
+ if (quoted) return quoted;
321
+ const patterns = [
322
+ /\bsearch(?: for)?\s+(.+?)(?:\s+on\s+(?:bsc|bnb|solana|sol|base|eth|ethereum)\b|$)/i,
323
+ /\bfind\s+(.+?)(?:\s+on\s+(?:bsc|bnb|solana|sol|base|eth|ethereum)\b|$)/i,
324
+ /\blook up\s+(.+?)(?:\s+on\s+(?:bsc|bnb|solana|sol|base|eth|ethereum)\b|$)/i,
325
+ /\bfor\s+(.+?)(?:\s+on\s+(?:bsc|bnb|solana|sol|base|eth|ethereum)\b|$)/i
326
+ ];
327
+ for (const pattern of patterns) {
328
+ const match = userText.match(pattern);
329
+ const value = match?.[1]?.trim();
330
+ if (value) return value.replace(/\s+/g, " ").trim();
331
+ }
332
+ const cleaned = userText.replace(/\b(binance-[a-z0-9-]+)\b/gi, " ").replace(
333
+ /\b(use|run|show|tell|give|fetch|pull|get|search|find|lookup|look up|query|token|info|market|data|detail|details|price|please|me|and)\b/gi,
334
+ " "
335
+ ).replace(/\b(on|in)\s+(bsc|bnb|solana|sol|base|eth|ethereum)\b/gi, " ").replace(/\b0x[a-fA-F0-9]{40}\b/g, " ").replace(/\b[1-9A-HJ-NP-Za-km-z]{32,44}\b/g, " ").replace(/\s+/g, " ").trim();
336
+ return cleaned || null;
337
+ }
338
+ function extractDirectBinanceAddressTarget(userText) {
339
+ const solanaAddress = extractFirstSolanaAddress(userText);
340
+ if (solanaAddress) {
341
+ return {
342
+ address: solanaAddress,
343
+ chain: "solana"
344
+ };
345
+ }
346
+ const evmAddress = extractFirstEvmAddress(userText);
347
+ if (!evmAddress) return null;
348
+ const chain = pickDirectBinanceChain(userText, ["bsc", "base", "eth"], "");
349
+ return {
350
+ address: evmAddress,
351
+ chain: chain || null
352
+ };
353
+ }
354
+ function resolveDirectBinanceTradingSignalCommand(userText) {
355
+ const chain = pickDirectBinanceChain(userText, ["solana", "bsc"], "solana");
356
+ const limit = pickDirectBinanceLimit(userText, 20, 100);
357
+ return {
358
+ kind: "run",
359
+ script: "signals.sh",
360
+ args: [chain, limit]
361
+ };
362
+ }
363
+ function resolveDirectBinanceCryptoMarketRankCommand(userText) {
364
+ const normalized = userText.toLowerCase();
365
+ let type = "trending";
366
+ if (/smart money|inflow/.test(normalized)) type = "smart-money";
367
+ else if (/trader|leaderboard|pnl|kol/.test(normalized)) type = "traders";
368
+ else if (/top search|searched|search ranking/.test(normalized))
369
+ type = "top-search";
370
+ else if (/\balpha\b/.test(normalized)) type = "alpha";
371
+ else if (/stock|tokenized/.test(normalized)) type = "stock";
372
+ else if (/meme/.test(normalized)) type = "meme";
373
+ const chain = pickDirectBinanceChain(
374
+ userText,
375
+ ["solana", "bsc", "base", "eth"],
376
+ ""
377
+ );
378
+ const limit = pickDirectBinanceLimit(userText, 20, 200);
379
+ return {
380
+ kind: "run",
381
+ script: "rankings.sh",
382
+ args: [type, chain || "all", limit]
383
+ };
384
+ }
385
+ function resolveDirectBinanceTokenInfoCommand(userText) {
386
+ const chain = pickDirectBinanceChain(
387
+ userText,
388
+ ["solana", "bsc", "base", "eth"],
389
+ ""
390
+ );
391
+ const target = extractDirectBinanceAddressTarget(userText);
392
+ if (target?.address) {
393
+ const targetChain = target.chain ?? (chain || null);
394
+ if (targetChain) {
395
+ return {
396
+ kind: "run",
397
+ script: "token-detail.sh",
398
+ args: [target.address, targetChain]
399
+ };
400
+ }
401
+ return {
402
+ kind: "run",
403
+ script: "search.sh",
404
+ args: [target.address]
405
+ };
406
+ }
407
+ const keyword = extractDirectBinanceSearchKeyword(userText);
408
+ if (!keyword) {
409
+ return {
410
+ kind: "ask",
411
+ text: "Please provide a token keyword, symbol, or contract address for binance-query-token-info."
412
+ };
413
+ }
414
+ return {
415
+ kind: "run",
416
+ script: "search.sh",
417
+ args: chain ? [keyword, chain] : [keyword]
418
+ };
419
+ }
420
+ function resolveDirectBinanceTokenAuditCommand(userText) {
421
+ const target = extractDirectBinanceAddressTarget(userText);
422
+ if (!target?.address) {
423
+ return {
424
+ kind: "ask",
425
+ text: "Please provide a token contract address for binance-query-token-audit."
426
+ };
427
+ }
428
+ if (!target.chain) {
429
+ return {
430
+ kind: "ask",
431
+ text: "Please specify the chain for that contract address: BSC, Base, Ethereum, or Solana."
432
+ };
433
+ }
434
+ return {
435
+ kind: "run",
436
+ script: "audit.sh",
437
+ args: [target.address, target.chain]
438
+ };
439
+ }
440
+ function resolveDirectBinanceAddressInfoCommand(userText) {
441
+ const target = extractDirectBinanceAddressTarget(userText);
442
+ if (!target?.address) {
443
+ return {
444
+ kind: "ask",
445
+ text: "Please provide a wallet address for binance-query-address-info."
446
+ };
447
+ }
448
+ if (!target.chain) {
449
+ return {
450
+ kind: "ask",
451
+ text: "Please specify the chain for that wallet address: BSC, Base, Ethereum, or Solana."
452
+ };
453
+ }
454
+ return {
455
+ kind: "run",
456
+ script: "balances.sh",
457
+ args: [target.address, target.chain]
458
+ };
459
+ }
460
+ function resolveDirectBinanceScriptCommand(skillSlug, userText) {
461
+ switch (skillSlug) {
462
+ case "binance-meme-rush":
463
+ return {
464
+ kind: "run",
465
+ ...resolveDirectBinanceMemeRushCommand(userText)
466
+ };
467
+ case "binance-trading-signal":
468
+ return resolveDirectBinanceTradingSignalCommand(userText);
469
+ case "binance-crypto-market-rank":
470
+ return resolveDirectBinanceCryptoMarketRankCommand(userText);
471
+ case "binance-query-token-info":
472
+ return resolveDirectBinanceTokenInfoCommand(userText);
473
+ case "binance-query-token-audit":
474
+ return resolveDirectBinanceTokenAuditCommand(userText);
475
+ case "binance-query-address-info":
476
+ return resolveDirectBinanceAddressInfoCommand(userText);
477
+ default:
478
+ return null;
479
+ }
480
+ }
481
+ const DIRECT_BINANCE_SUMMARY_INPUT_MAX_CHARS = 12e3;
482
+ const DIRECT_BINANCE_SUMMARY_DEFAULT_ITEMS = 5;
483
+ const DIRECT_BINANCE_SUMMARY_MAX_DEPTH = 4;
484
+ function shouldOmitDirectBinanceSummaryKey(key) {
485
+ return /^(?:icon|iconUrl|image|imageUrl|logo|logoUrl|avatar|avatarUrl|cover|coverUrl)$/i.test(
486
+ key
487
+ ) || /^(?:website|websites|twitter|telegram|discord|medium|social|socials|links?|x)$/i.test(
488
+ key
489
+ );
490
+ }
491
+ function compactDirectBinanceSummaryValue(value, itemLimit, depth = 0) {
492
+ if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
493
+ return value;
494
+ }
495
+ if (depth >= DIRECT_BINANCE_SUMMARY_MAX_DEPTH) {
496
+ if (Array.isArray(value)) {
497
+ return value.slice(0, Math.min(itemLimit, 3)).map(
498
+ (item) => compactDirectBinanceSummaryValue(item, itemLimit, depth + 1)
499
+ );
500
+ }
501
+ if (typeof value === "object") {
502
+ const objectValue = value;
503
+ const compactObject = {};
504
+ for (const [key, entry] of Object.entries(objectValue).slice(0, 8)) {
505
+ if (shouldOmitDirectBinanceSummaryKey(key)) continue;
506
+ if (entry === null || typeof entry === "string" || typeof entry === "number" || typeof entry === "boolean") {
507
+ compactObject[key] = entry;
508
+ }
509
+ }
510
+ return compactObject;
511
+ }
512
+ return void 0;
513
+ }
514
+ if (Array.isArray(value)) {
515
+ return value.slice(0, itemLimit).map(
516
+ (item) => compactDirectBinanceSummaryValue(item, itemLimit, depth + 1)
517
+ ).filter((item) => item !== void 0);
518
+ }
519
+ if (typeof value === "object") {
520
+ const objectValue = value;
521
+ const scalarEntries = [];
522
+ const complexEntries = [];
523
+ for (const [key, entry] of Object.entries(objectValue)) {
524
+ if (shouldOmitDirectBinanceSummaryKey(key)) continue;
525
+ if (entry === null || typeof entry === "string" || typeof entry === "number" || typeof entry === "boolean") {
526
+ scalarEntries.push([key, entry]);
527
+ } else {
528
+ complexEntries.push([key, entry]);
529
+ }
530
+ }
531
+ const maxKeys = depth === 0 ? 24 : depth === 1 ? 16 : 10;
532
+ const compactObject = {};
533
+ for (const [key, entry] of [...scalarEntries, ...complexEntries].slice(
534
+ 0,
535
+ maxKeys
536
+ )) {
537
+ const compactEntry = compactDirectBinanceSummaryValue(
538
+ entry,
539
+ key === "data" ? itemLimit : Math.min(itemLimit, 6),
540
+ depth + 1
541
+ );
542
+ if (compactEntry === void 0) continue;
543
+ if (Array.isArray(compactEntry) && compactEntry.length === 0) continue;
544
+ if (compactEntry && typeof compactEntry === "object" && !Array.isArray(compactEntry) && Object.keys(compactEntry).length === 0) {
545
+ continue;
546
+ }
547
+ compactObject[key] = compactEntry;
548
+ }
549
+ return compactObject;
550
+ }
551
+ return String(value);
552
+ }
553
+ function buildDirectBinanceSummaryInput(unwrapped, explicitCount) {
554
+ const itemLimit = explicitCount ?? DIRECT_BINANCE_SUMMARY_DEFAULT_ITEMS;
555
+ try {
556
+ const parsed = JSON.parse(unwrapped);
557
+ const compact = compactDirectBinanceSummaryValue(parsed, itemLimit);
558
+ if (compact !== void 0) {
559
+ const compactText = JSON.stringify(compact, null, 2);
560
+ if (compactText.trim()) {
561
+ return compactText;
562
+ }
563
+ }
564
+ } catch {
565
+ }
566
+ return unwrapped;
567
+ }
568
+ function wantsRawBinanceSkillResult(userText) {
569
+ const normalized = userText.toLowerCase();
570
+ return /\braw\b/.test(normalized) || /\bjson\b/.test(normalized) || /\bverbatim\b/.test(normalized) || /\bfull (?:response|result|output)\b/.test(normalized) || /\bexact (?:response|result|output)\b/.test(normalized);
571
+ }
572
+ const FENCED_JSON_RE_SERVER = /```(?:json)?\s*\n([\s\S]*?)```/;
573
+ function unwrapDirectBinanceSkillResult(rawText) {
574
+ const fencedBlocks = Array.from(
575
+ rawText.matchAll(new RegExp(FENCED_JSON_RE_SERVER.source, "g"))
576
+ ).map((match) => match[1]?.trim() ?? "").filter((block) => block.length > 0);
577
+ if (fencedBlocks.length > 0) {
578
+ return fencedBlocks.join("\n\n");
579
+ }
580
+ return rawText.replace(/^Script executed successfully:\s*/i, "").replace(/^Script execution failed:\s*/i, "").trim();
581
+ }
582
+ function normalizeDirectBinanceSummaryText(summary) {
583
+ return summary.replace(/\*\*/g, "").replace(/^[ \t]*[-*][ \t]+/gm, "").replace(/^[ \t]*\d+\.\s+/gm, "").replace(/^#{1,6}\s+/gm, "").replace(
584
+ /\n?(?:For more details or the raw JSON, feel free to ask\.?|You can ask for the raw JSON if you want it\.?|If you need the raw JSON details, feel free to ask\.?)\s*$/i,
585
+ ""
586
+ ).replace(/\n{3,}/g, "\n\n").trim();
587
+ }
588
+ async function summarizeDirectBinanceSkillResult(runtime, skillSlug, userText, rawText) {
589
+ const fallback = () => `I ran ${skillSlug} and got a Binance skill result, but I couldn't format the raw details cleanly here.`;
590
+ const unwrapped = unwrapDirectBinanceSkillResult(rawText);
591
+ if (!unwrapped) return fallback();
592
+ const explicitCount = extractExplicitDirectBinanceCount(userText, 50);
593
+ const compactInput = buildDirectBinanceSummaryInput(unwrapped, explicitCount);
594
+ const resultSnippet = compactInput.length > DIRECT_BINANCE_SUMMARY_INPUT_MAX_CHARS ? `${compactInput.slice(0, DIRECT_BINANCE_SUMMARY_INPUT_MAX_CHARS)}
595
+
596
+ [truncated]` : compactInput;
597
+ const prompt = [
598
+ "You are formatting the result of a Binance skill for the end user.",
599
+ "The official skill instructions say to run the skill first and then summarize the results.",
600
+ "",
601
+ `User request: ${userText}`,
602
+ `Skill: ${skillSlug}`,
603
+ explicitCount ? `The user explicitly requested ${explicitCount} items. Return ${explicitCount} distinct items if the result contains that many.` : "If the user did not request a count, choose a sensible concise amount.",
604
+ "",
605
+ "Rules:",
606
+ "- Answer the user's request directly using only the result below.",
607
+ "- Default to a concise summary, not raw JSON.",
608
+ "- If the result is a ranking or list, show at most 5 items unless the user explicitly requested a different count.",
609
+ "- Output plain text only.",
610
+ "- Do not use markdown, bullets, numbered lists, bold markers, or code fences.",
611
+ "- Prefer a clean title line followed by compact 'Label: value' lines, with blank lines between items when listing multiple entries.",
612
+ "- Do not prefix lines with generic labels like 'Label:' or 'Item:'. Use the actual field name directly.",
613
+ "- Mention the chain when it is present in the result.",
614
+ "- Ignore icon URLs, image links, and social links unless the user explicitly asked for them.",
615
+ "- Do not mention scripts, stdout, code fences, or internal tooling.",
616
+ "- Do not invent missing fields. If a field is unavailable, omit it.",
617
+ "- If the result is an error, explain it briefly and suggest one next step.",
618
+ "- Do not append any follow-up sentence about raw JSON, more details, or next questions.",
619
+ "",
620
+ "Skill result:",
621
+ resultSnippet
622
+ ].join("\n");
623
+ try {
624
+ const summary = await runtime.useModel(ModelType.TEXT_SMALL, {
625
+ prompt,
626
+ maxTokens: 700,
627
+ temperature: 0.2
628
+ });
629
+ const clean = summary?.trim() ? normalizeDirectBinanceSummaryText(summary.trim()) : "";
630
+ return clean || fallback();
631
+ } catch (err) {
632
+ runtime.logger?.warn(
633
+ {
634
+ src: "eliza-api",
635
+ skillSlug,
636
+ error: err instanceof Error ? err.message : String(err)
637
+ },
638
+ "[eliza-api] Binance skill summarization failed; suppressing raw output"
639
+ );
640
+ return fallback();
641
+ }
642
+ }
643
+ async function rewriteRawDirectBinanceSkillResult(runtime, skillSlug, userText, rawText) {
644
+ const fallback = () => `I ran ${skillSlug} and got the requested raw Binance skill payload, but I couldn't format it safely here.`;
645
+ const unwrapped = unwrapDirectBinanceSkillResult(rawText) || rawText;
646
+ const boundedPayload = unwrapped.length > DIRECT_BINANCE_SUMMARY_INPUT_MAX_CHARS ? `${unwrapped.slice(0, DIRECT_BINANCE_SUMMARY_INPUT_MAX_CHARS)}
647
+
648
+ [truncated]` : unwrapped;
649
+ const prompt = [
650
+ "Write a brief character-voiced response that includes the requested raw Binance skill payload.",
651
+ 'Return strict JSON only: {"response":"..."}.',
652
+ "",
653
+ "Rules:",
654
+ "- Preserve the raw payload exactly inside the response as much as possible.",
655
+ "- Add only a short natural-language wrapper before the payload.",
656
+ "- Do not invent fields, interpretation, or extra analysis.",
657
+ "- If the payload is truncated, say it is truncated.",
658
+ "",
659
+ `Character: ${JSON.stringify({
660
+ name: runtime.character?.name,
661
+ system: runtime.character?.system,
662
+ bio: runtime.character?.bio,
663
+ style: runtime.character?.style
664
+ })}`,
665
+ `User request: ${JSON.stringify(userText)}`,
666
+ `Skill: ${JSON.stringify(skillSlug)}`,
667
+ `Raw payload: ${JSON.stringify(boundedPayload)}`
668
+ ].join("\n");
669
+ try {
670
+ const raw = await runtime.useModel(ModelType.TEXT_SMALL, {
671
+ prompt,
672
+ maxTokens: 900,
673
+ temperature: 0.1,
674
+ providerOptions: { eliza: { thinking: "off" } }
675
+ });
676
+ const parsed = JSON.parse(String(raw).trim());
677
+ return typeof parsed.response === "string" && parsed.response.trim() ? parsed.response.trim() : fallback();
678
+ } catch (err) {
679
+ runtime.logger?.warn?.(
680
+ {
681
+ src: "eliza-api",
682
+ skillSlug,
683
+ error: err instanceof Error ? err.message : String(err)
684
+ },
685
+ "[eliza-api] Binance raw skill rewrite failed; suppressing raw output"
686
+ );
687
+ return fallback();
688
+ }
689
+ }
690
+ async function maybeHandleDirectBinanceSkillRequest(runtime, message, appendIncomingText, replaceText) {
691
+ const userText = extractCompatTextContent(message.content)?.trim();
692
+ if (!userText) return null;
693
+ const skillSlug = extractDirectBinanceSkillSlug(userText);
694
+ if (!skillSlug) return null;
695
+ if (!shouldExposeBinanceSkillId(skillSlug)) {
696
+ const visibleSkills = Array.from(EXPOSED_BINANCE_SKILL_IDS).sort().join(", ");
697
+ return `The Binance skill "${skillSlug}" is currently hidden in this build. Available Binance skills: ${visibleSkills}.`;
698
+ }
699
+ const service = runtime.getService("AGENT_SKILLS_SERVICE");
700
+ const hasSkill = typeof service?.getLoadedSkill === "function" ? Boolean(service.getLoadedSkill(skillSlug)) : typeof service?.getLoadedSkills === "function" ? service.getLoadedSkills().some(
701
+ (skill) => typeof skill.slug === "string" && skill.slug === skillSlug
702
+ ) : false;
703
+ if (!hasSkill) return null;
704
+ const runtimeActions = Array.isArray(
705
+ runtime.actions
706
+ ) ? runtime.actions : [];
707
+ const useSkillAction = runtimeActions.find(
708
+ (action) => action.name === "USE_SKILL"
709
+ );
710
+ const command = resolveDirectBinanceScriptCommand(skillSlug, userText);
711
+ if (!command) {
712
+ return null;
713
+ }
714
+ if (command.kind === "ask") {
715
+ appendIncomingText(command.text);
716
+ return command.text;
717
+ }
718
+ if (typeof useSkillAction?.handler === "function") {
719
+ const loadingHints = {
720
+ "binance-meme-rush": "Fetching meme tokens from Binance...",
721
+ "binance-trading-signal": "Fetching trading signals...",
722
+ "binance-crypto-market-rank": "Fetching market rankings...",
723
+ "binance-query-token-info": "Looking up token info...",
724
+ "binance-query-token-audit": "Running token audit...",
725
+ "binance-query-address-info": "Checking wallet balances..."
726
+ };
727
+ appendIncomingText(loadingHints[skillSlug] ?? "Fetching Binance data...");
728
+ let directRunText = "";
729
+ runtime.logger?.info(
730
+ {
731
+ src: "eliza-api",
732
+ action: "USE_SKILL",
733
+ skillSlug,
734
+ script: command.script,
735
+ args: command.args
736
+ },
737
+ `[eliza-api] Direct Binance script dispatch: ${skillSlug}/${command.script}`
738
+ );
739
+ const runResult = await Promise.resolve(
740
+ useSkillAction.handler(
741
+ runtime,
742
+ message,
743
+ void 0,
744
+ {
745
+ slug: skillSlug,
746
+ mode: "script",
747
+ script: command.script,
748
+ args: command.args
749
+ },
750
+ async (content) => {
751
+ const chunk = content && typeof content === "object" ? extractCompatTextContent(content) : "";
752
+ if (!chunk) return [];
753
+ directRunText = chunk;
754
+ return [];
755
+ },
756
+ []
757
+ )
758
+ );
759
+ const rawDirectText = directRunText.trim().length > 0 ? directRunText : runResult && typeof runResult === "object" && "text" in runResult && typeof runResult.text === "string" ? runResult.text : "";
760
+ if (rawDirectText.trim().length > 0) {
761
+ const finalText = wantsRawBinanceSkillResult(userText) ? await rewriteRawDirectBinanceSkillResult(
762
+ runtime,
763
+ skillSlug,
764
+ userText,
765
+ rawDirectText
766
+ ) : await summarizeDirectBinanceSkillResult(
767
+ runtime,
768
+ skillSlug,
769
+ userText,
770
+ rawDirectText
771
+ );
772
+ if (replaceText) {
773
+ replaceText(finalText);
774
+ } else {
775
+ appendIncomingText(finalText);
776
+ }
777
+ return finalText;
778
+ }
779
+ }
780
+ return null;
781
+ }
782
+ export {
783
+ executeFallbackParsedActions,
784
+ inferBalanceChainFromText,
785
+ isBalanceIntent,
786
+ maybeHandleDirectBinanceSkillRequest,
787
+ parseFallbackActionBlocks,
788
+ shouldForceCheckBalanceFallback
789
+ };
790
+ //# sourceMappingURL=binance-skill-helpers.js.map