@senpi/runtime 3.0.0-dev.openclaw-upgrade-mai.20260623210452 → 3.0.0-dev.runtime-phase-2.20260623210537

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 (196) hide show
  1. package/README.md +9 -10
  2. package/dist/actions/decision-engine.d.ts.map +1 -1
  3. package/dist/actions/decision-engine.js +0 -3
  4. package/dist/actions/decision-engine.js.map +1 -1
  5. package/dist/actions/open-position/open-position.action.d.ts.map +1 -1
  6. package/dist/actions/open-position/open-position.action.js +2 -6
  7. package/dist/actions/open-position/open-position.action.js.map +1 -1
  8. package/dist/cli/guide-commands.d.ts.map +1 -1
  9. package/dist/cli/guide-commands.js +56 -43
  10. package/dist/cli/guide-commands.js.map +1 -1
  11. package/dist/cli/senpi-commands.d.ts.map +1 -1
  12. package/dist/cli/senpi-commands.js +108 -0
  13. package/dist/cli/senpi-commands.js.map +1 -1
  14. package/dist/constants/dsl/index.d.ts +0 -2
  15. package/dist/constants/dsl/index.d.ts.map +1 -1
  16. package/dist/constants/dsl/index.js +0 -2
  17. package/dist/constants/dsl/index.js.map +1 -1
  18. package/dist/dsl/engine-client/config-mapping.d.ts +0 -7
  19. package/dist/dsl/engine-client/config-mapping.d.ts.map +1 -1
  20. package/dist/dsl/engine-client/config-mapping.js +2 -16
  21. package/dist/dsl/engine-client/config-mapping.js.map +1 -1
  22. package/dist/dsl/events/handlers.d.ts +2 -18
  23. package/dist/dsl/events/handlers.d.ts.map +1 -1
  24. package/dist/dsl/events/handlers.js +213 -302
  25. package/dist/dsl/events/handlers.js.map +1 -1
  26. package/dist/dsl/monitor/create-monitor.d.ts +0 -15
  27. package/dist/dsl/monitor/create-monitor.d.ts.map +1 -1
  28. package/dist/dsl/monitor/create-monitor.js +9 -44
  29. package/dist/dsl/monitor/create-monitor.js.map +1 -1
  30. package/dist/dsl/monitor/process-one-position.d.ts.map +1 -1
  31. package/dist/dsl/monitor/process-one-position.js +1 -24
  32. package/dist/dsl/monitor/process-one-position.js.map +1 -1
  33. package/dist/dsl/plugin/index.d.ts +1 -16
  34. package/dist/dsl/plugin/index.d.ts.map +1 -1
  35. package/dist/dsl/plugin/index.js +4 -35
  36. package/dist/dsl/plugin/index.js.map +1 -1
  37. package/dist/dsl/plugin/options.d.ts +0 -18
  38. package/dist/dsl/plugin/options.d.ts.map +1 -1
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +0 -4
  41. package/dist/index.js.map +1 -1
  42. package/dist/runtime/create-scanner-module.d.ts +3 -4
  43. package/dist/runtime/create-scanner-module.d.ts.map +1 -1
  44. package/dist/runtime/create-scanner-module.js +5 -14
  45. package/dist/runtime/create-scanner-module.js.map +1 -1
  46. package/dist/runtime/create-scanner-providers-for-run.d.ts.map +1 -1
  47. package/dist/runtime/create-scanner-providers-for-run.js +1 -12
  48. package/dist/runtime/create-scanner-providers-for-run.js.map +1 -1
  49. package/dist/runtime/load-runtime-config.js +1 -1
  50. package/dist/runtime/load-runtime-config.js.map +1 -1
  51. package/dist/runtime/map-strategies-registration.js +8 -7
  52. package/dist/runtime/map-strategies-registration.js.map +1 -1
  53. package/dist/runtime/map-strategies.d.ts.map +1 -1
  54. package/dist/runtime/map-strategies.js +3 -12
  55. package/dist/runtime/map-strategies.js.map +1 -1
  56. package/dist/runtime/reconcile-state.d.ts +0 -44
  57. package/dist/runtime/reconcile-state.d.ts.map +1 -1
  58. package/dist/runtime/reconcile-state.js +44 -80
  59. package/dist/runtime/reconcile-state.js.map +1 -1
  60. package/dist/runtime/risk-guard.d.ts.map +1 -1
  61. package/dist/runtime/risk-guard.js +12 -17
  62. package/dist/runtime/risk-guard.js.map +1 -1
  63. package/dist/runtime/runtime-schema.d.ts +995 -2855
  64. package/dist/runtime/runtime-schema.d.ts.map +1 -1
  65. package/dist/runtime/runtime-schema.js +40 -133
  66. package/dist/runtime/runtime-schema.js.map +1 -1
  67. package/dist/runtime/runtime.d.ts +0 -26
  68. package/dist/runtime/runtime.d.ts.map +1 -1
  69. package/dist/runtime/runtime.js +5 -233
  70. package/dist/runtime/runtime.js.map +1 -1
  71. package/dist/runtime/scanner-registry.d.ts +1 -1
  72. package/dist/runtime/scanner-registry.d.ts.map +1 -1
  73. package/dist/runtime/scanner-registry.js +12 -3
  74. package/dist/runtime/scanner-registry.js.map +1 -1
  75. package/dist/runtime/supervisor/long-running-supervisor.d.ts.map +1 -1
  76. package/dist/runtime/supervisor/long-running-supervisor.js +1 -1
  77. package/dist/runtime/supervisor/long-running-supervisor.js.map +1 -1
  78. package/dist/runtime/supervisor/orphan-sweep.js +1 -1
  79. package/dist/runtime/supervisor/orphan-sweep.js.map +1 -1
  80. package/dist/runtime/supervisor/supervisor-utils.d.ts +1 -1
  81. package/dist/runtime/supervisor/supervisor-utils.d.ts.map +1 -1
  82. package/dist/runtime/supervisor/supervisor-utils.js +1 -1
  83. package/dist/runtime/supervisor/supervisor-utils.js.map +1 -1
  84. package/dist/runtime-api/intake/intake-mount.d.ts.map +1 -1
  85. package/dist/runtime-api/intake/intake-mount.js +36 -28
  86. package/dist/runtime-api/intake/intake-mount.js.map +1 -1
  87. package/dist/runtime-api/intake/process-signal-post.d.ts.map +1 -1
  88. package/dist/runtime-api/intake/process-signal-post.js +0 -0
  89. package/dist/runtime-api/intake/process-signal-post.js.map +1 -1
  90. package/dist/runtime-api/intake/scanner-launcher.d.ts +4 -18
  91. package/dist/runtime-api/intake/scanner-launcher.d.ts.map +1 -1
  92. package/dist/runtime-api/intake/scanner-launcher.js +3 -24
  93. package/dist/runtime-api/intake/scanner-launcher.js.map +1 -1
  94. package/dist/runtime-api/intake/types.d.ts +0 -6
  95. package/dist/runtime-api/intake/types.d.ts.map +1 -1
  96. package/dist/runtime-api/routes/signals.schema.d.ts +0 -1
  97. package/dist/runtime-api/routes/signals.schema.d.ts.map +1 -1
  98. package/dist/runtime-api/routes/signals.schema.js +0 -5
  99. package/dist/runtime-api/routes/signals.schema.js.map +1 -1
  100. package/dist/scanners/external/liquidation-watchdog/README.md +107 -0
  101. package/dist/scanners/external/liquidation-watchdog/liquidation-watchdog.yaml +48 -0
  102. package/dist/scanners/external/liquidation-watchdog/producer.mjs +336 -0
  103. package/dist/scanners/external/momentum/README.md +148 -0
  104. package/dist/scanners/external/momentum/momentum.yaml +116 -0
  105. package/dist/scanners/external/momentum/producer.mjs +251 -0
  106. package/dist/scanners/external/scaffold/__main__.py +24 -65
  107. package/dist/scanners/external/scaffold/delivery.py +22 -56
  108. package/dist/scanners/external/scaffold/entrypoint_loader.py +48 -42
  109. package/dist/scanners/external/scaffold/journal.py +2 -13
  110. package/dist/scanners/external/scaffold/scaffold.py +128 -159
  111. package/dist/scanners/external/scaffold/signal_envelope.py +34 -177
  112. package/dist/scanners/external/shared/ingest.mjs +112 -0
  113. package/dist/scanners/external-scanner-receiver.d.ts +0 -6
  114. package/dist/scanners/external-scanner-receiver.d.ts.map +1 -1
  115. package/dist/scanners/external-scanner-receiver.js +1 -14
  116. package/dist/scanners/external-scanner-receiver.js.map +1 -1
  117. package/dist/scripts/run-dsl-standalone-live.d.ts +1 -1
  118. package/dist/scripts/run-dsl-standalone-live.js +3 -5
  119. package/dist/scripts/run-dsl-standalone-live.js.map +1 -1
  120. package/dist/senpi/client.d.ts +0 -12
  121. package/dist/senpi/client.d.ts.map +1 -1
  122. package/dist/senpi/client.js +2 -31
  123. package/dist/senpi/client.js.map +1 -1
  124. package/dist/state/state-manager.d.ts +0 -17
  125. package/dist/state/state-manager.d.ts.map +1 -1
  126. package/dist/state/state-manager.js +0 -28
  127. package/dist/state/state-manager.js.map +1 -1
  128. package/dist/strategy/strategy-state.d.ts.map +1 -1
  129. package/dist/strategy/strategy-state.js +1 -7
  130. package/dist/strategy/strategy-state.js.map +1 -1
  131. package/dist/tracking/constants.d.ts.map +1 -1
  132. package/dist/tracking/constants.js +0 -2
  133. package/dist/tracking/constants.js.map +1 -1
  134. package/dist/types/dsl/index.d.ts +1 -1
  135. package/dist/types/dsl/index.d.ts.map +1 -1
  136. package/dist/types/scanner.d.ts +0 -7
  137. package/dist/types/scanner.d.ts.map +1 -1
  138. package/examples/README.md +89 -0
  139. package/examples/scanners-consumer-quickstart.mjs +134 -0
  140. package/examples/scanners-emerging-movers-v4.mjs +287 -0
  141. package/examples/scanners-liquidation-watchdog.mjs +341 -0
  142. package/examples/scanners-live-mcp.mjs +208 -0
  143. package/examples/scanners-multi-strategy.mjs +165 -0
  144. package/examples/scanners-position-tracker-e2e.mjs +225 -0
  145. package/examples/scanners-scheduled-events.mjs +96 -0
  146. package/examples/scanners-senpi-provider-client.mjs +182 -0
  147. package/examples/scanners-single-strategy.mjs +198 -0
  148. package/examples/strategies/README.md +12 -17
  149. package/examples/strategies/dsl-showcase.yaml +68 -0
  150. package/examples/strategies/dsl.yaml +51 -0
  151. package/examples/strategies/fox-minimal-loosened.yaml +240 -0
  152. package/examples/strategies/fox-minimal.yaml +242 -0
  153. package/examples/strategies/minimal.yaml +46 -0
  154. package/examples/strategies/momentum/how-it-works.md +48 -0
  155. package/examples/strategies/momentum/momentum-guarded.yaml +161 -0
  156. package/examples/strategies/risk-showcase.yaml +93 -0
  157. package/examples/strategies/viper.yaml +67 -0
  158. package/examples/strategies/wolf.yaml +72 -0
  159. package/examples/yamls/sample-with-dsl-and-emerging-movers.yaml +123 -0
  160. package/package.json +1 -1
  161. package/dist/runtime/reconcile-decide.d.ts +0 -73
  162. package/dist/runtime/reconcile-decide.d.ts.map +0 -1
  163. package/dist/runtime/reconcile-decide.js +0 -166
  164. package/dist/runtime/reconcile-decide.js.map +0 -1
  165. package/dist/runtime/reconcile-run.d.ts +0 -62
  166. package/dist/runtime/reconcile-run.d.ts.map +0 -1
  167. package/dist/runtime/reconcile-run.js +0 -173
  168. package/dist/runtime/reconcile-run.js.map +0 -1
  169. package/dist/scanners/external/scaffold/ctx.py +0 -78
  170. package/dist/scanners/external/scaffold/requirements.txt +0 -11
  171. package/dist/scanners/external/scaffold/senpi_mcp.py +0 -250
  172. package/dist/scanners/external/scaffold/state_manager.py +0 -175
  173. package/dist/utils/keyed-mutex.d.ts +0 -37
  174. package/dist/utils/keyed-mutex.d.ts.map +0 -1
  175. package/dist/utils/keyed-mutex.js +0 -77
  176. package/dist/utils/keyed-mutex.js.map +0 -1
  177. package/examples/strategies/iguana/README.md +0 -135
  178. package/examples/strategies/iguana/recipe.yaml +0 -137
  179. package/examples/strategies/iguana/scanners/scan.py +0 -243
  180. package/examples/strategies/iguana/scanners/scoring.py +0 -152
  181. package/examples/strategies/raptor/README.md +0 -156
  182. package/examples/strategies/raptor/recipe.yaml +0 -154
  183. package/examples/strategies/raptor/scanners/scan.py +0 -349
  184. package/examples/strategies/raptor/scanners/scoring.py +0 -452
  185. package/examples/strategies/spider/README.md +0 -97
  186. package/examples/strategies/spider/scalp/recipe.yaml +0 -129
  187. package/examples/strategies/spider/scalp/scanners/scan.py +0 -219
  188. package/examples/strategies/spider/scalp/scanners/scoring.py +0 -179
  189. package/examples/strategies/spider/swing/recipe.yaml +0 -141
  190. package/examples/strategies/spider/swing/scanners/scan.py +0 -334
  191. package/examples/strategies/spider/swing/scanners/scoring.py +0 -184
  192. package/examples/strategies/turbine/README.md +0 -167
  193. package/examples/strategies/turbine/recipe-runners.yaml +0 -123
  194. package/examples/strategies/turbine/recipe-volume.yaml +0 -129
  195. package/examples/strategies/turbine/scanners/scan.py +0 -283
  196. package/examples/strategies/turbine/scanners/scoring.py +0 -190
@@ -1,190 +0,0 @@
1
- """TURBINE — pure rotation/direction/spread functions (port of turbine-producer.py v3.2.2).
2
-
3
- Ported VERBATIM from senpi-skills/turbine/scripts/turbine-producer.py (choose_direction,
4
- pick_rotation_asset, spread parsing) and turbine_config.py (normalize_coin_key). No I/O, no
5
- MCP, no daemon — pure and unit-testable. `scan.py` fetches per-asset market data via
6
- ctx.senpi_mcp and hands it to these helpers.
7
-
8
- Both turbine legs (volume + runners) share THIS scoring module: the source ran the identical
9
- volume-rotation alpha on both wallets and let the wallet boundary (DSL preset + sizing) select
10
- behavior. So there is no per-leg branch here — only sizing/exit differ, and those live in the
11
- recipe YAMLs, not in the signal logic.
12
-
13
- Source thresholds preserved exactly:
14
- - Universe MAIN = [BTC, ETH, SOL, HYPE]; XYZ = [xyz:BRENTOIL, xyz:GOLD, xyz:SPX].
15
- - Direction = funding fade: LONG_CROWDED/LONG_HEAVY -> SHORT (funding_fade_short),
16
- SHORT_CROWDED/SHORT_HEAVY -> LONG (funding_fade_long), else random LONG/SHORT
17
- (alternate_neutral).
18
- - Rotation: probabilistic pool pick (random.random() < xyz_weight -> XYZ pool, else MAIN),
19
- then a deterministic rotation index inside the pool; skip held + 90s post-close cooldown;
20
- fall through to the OTHER pool if the chosen one is exhausted.
21
- - Spread gate: main <= spread_main_bps (3), xyz <= spread_xyz_bps (10). spread_bps from the
22
- top-of-book mid: ((ask - bid) / mid) * 10000.
23
- """
24
-
25
- import random
26
- import time
27
-
28
-
29
- # ── Universe (shared by both wallets) ──
30
-
31
- VOLUME_XYZ = ["xyz:BRENTOIL", "xyz:GOLD", "xyz:SPX"]
32
- VOLUME_MAIN = ["BTC", "ETH", "SOL", "HYPE"]
33
-
34
- POST_CLOSE_COOLDOWN_SECONDS = 90
35
-
36
-
37
- def is_xyz(asset):
38
- return asset.startswith("xyz:")
39
-
40
-
41
- def normalize_coin_key(coin):
42
- """Canonicalize a coin string for held_keys / cooldown sets.
43
-
44
- Port of turbine_config.normalize_coin_key (v3.2.2): preserve the xyz: prefix so that
45
- main:HYPE and xyz:HYPE are distinct slot occupiers. Lowercase the prefix, uppercase the
46
- symbol; bare symbols are uppercased.
47
- """
48
- if not coin:
49
- return ""
50
- s = coin.strip()
51
- if ":" in s:
52
- prefix, _, symbol = s.partition(":")
53
- return f"{prefix.lower()}:{symbol.upper()}"
54
- return s.upper()
55
-
56
-
57
- def safe_float(v, d=0.0):
58
- try:
59
- return float(v)
60
- except (TypeError, ValueError):
61
- return d
62
-
63
-
64
- # ── Direction: funding fade (verbatim from producer.choose_direction) ──
65
-
66
- def choose_direction(regime, rng=random):
67
- """Funding fade. Crowded longs -> SHORT, crowded shorts -> LONG, flat -> coin flip.
68
-
69
- Returns (direction, thesis). `rng` is injectable for deterministic tests; the source used
70
- the module-level `random`.
71
- """
72
- r = (regime or "").upper()
73
- if r in ("LONG_CROWDED", "LONG_HEAVY"):
74
- return "SHORT", "funding_fade_short"
75
- if r in ("SHORT_CROWDED", "SHORT_HEAVY"):
76
- return "LONG", "funding_fade_long"
77
- return rng.choice(["LONG", "SHORT"]), "alternate_neutral"
78
-
79
-
80
- # ── Spread parsing (verbatim from producer.query_asset_data) ──
81
-
82
- def _lvl_px(lvl):
83
- if isinstance(lvl, dict):
84
- return safe_float(lvl.get("px", lvl.get("price", 0)))
85
- if isinstance(lvl, list) and lvl:
86
- return safe_float(lvl[0])
87
- return 0.0
88
-
89
-
90
- def parse_asset_data(resp):
91
- """Extract bid/ask/mid/spread_bps + funding regime from a market_get_asset_data response.
92
-
93
- Returns a dict or None when the order book is missing / one-sided / non-positive (the
94
- source treated all of these as 'skip this asset'). Mirrors producer.query_asset_data
95
- exactly: top-of-book levels, mid = (bid+ask)/2, spread_bps = ((ask-bid)/mid)*10000.
96
- """
97
- if not resp or not isinstance(resp, dict):
98
- return None
99
- ad = resp.get("data", resp)
100
- if not isinstance(ad, dict):
101
- return None
102
- ob = ad.get("order_book") or ad.get("orderBook") or {}
103
- levels = ob.get("levels", [])
104
- if not isinstance(levels, list) or len(levels) < 2:
105
- return None
106
- bids, asks = levels[0], levels[1]
107
- if not bids or not asks:
108
- return None
109
- bid = _lvl_px(bids[0])
110
- ask = _lvl_px(asks[0])
111
- if bid <= 0 or ask <= 0:
112
- return None
113
- mid = (bid + ask) / 2.0
114
- spread_bps = ((ask - bid) / mid) * 10000 if mid > 0 else 999
115
-
116
- funding_regime = (
117
- ad.get("funding_regime") or ad.get("fundingRegime") or "UNKNOWN"
118
- ).upper()
119
- funding_annualized_pct = safe_float(
120
- ad.get("funding_annualized_pct") or ad.get("fundingAnnualizedPct") or 0
121
- )
122
- return {
123
- "bid": bid,
124
- "ask": ask,
125
- "mid": mid,
126
- "spread_bps": round(spread_bps, 3),
127
- "funding_regime": funding_regime,
128
- "funding_annualized_pct": funding_annualized_pct,
129
- }
130
-
131
-
132
- def spread_ok(asset, spread_bps, spread_main_bps, spread_xyz_bps):
133
- """Spread gate: xyz assets get the wider xyz cap, everything else the main cap."""
134
- max_spread = spread_xyz_bps if is_xyz(asset) else spread_main_bps
135
- return spread_bps <= max_spread
136
-
137
-
138
- # ── Rotation pick (verbatim from producer.pick_rotation_asset) ──
139
-
140
- def pick_rotation_asset(rot_idx, xyz_weight, held_set, last_closed, now=None, rng=random):
141
- """Pick the next rotation asset.
142
-
143
- Probabilistic pool pick (random.random() < xyz_weight -> XYZ pool, else MAIN) + a
144
- deterministic rotation index inside the chosen pool. Skips assets already held and assets
145
- closed within POST_CLOSE_COOLDOWN_SECONDS (90s). Falls through to the OTHER pool if the
146
- chosen one is exhausted. Returns (asset|None, new_rot_idx).
147
-
148
- `now`/`rng` are injectable for deterministic tests; the source used time.time() / random.
149
- """
150
- if now is None:
151
- now = time.time()
152
-
153
- def _try_pool(pool, idx):
154
- n = len(pool)
155
- for _ in range(n):
156
- candidate = pool[idx % n]
157
- idx = (idx + 1) % n
158
- coin_key = normalize_coin_key(candidate)
159
- if coin_key in held_set:
160
- continue
161
- last = last_closed.get(coin_key, {})
162
- if last and (now - last.get("ts", 0)) < POST_CLOSE_COOLDOWN_SECONDS:
163
- continue
164
- return candidate, idx
165
- return None, idx
166
-
167
- use_xyz = rng.random() < xyz_weight
168
- pool = VOLUME_XYZ if use_xyz else VOLUME_MAIN
169
- asset, rot_idx = _try_pool(pool, rot_idx)
170
- if asset is not None:
171
- return asset, rot_idx
172
-
173
- other = VOLUME_MAIN if use_xyz else VOLUME_XYZ
174
- asset, rot_idx = _try_pool(other, rot_idx)
175
- return asset, rot_idx
176
-
177
-
178
- def clamp_leverage(desired, venue_max):
179
- """Clamp desired leverage to the asset's Hyperliquid venue max.
180
-
181
- Turbine's source used a fixed 5x and relied on the runtime to clamp per-asset. We carry the
182
- same defensive clamp the spider port uses so a low-venue-cap asset never over-levers.
183
- """
184
- try:
185
- venue = int(venue_max)
186
- except (TypeError, ValueError):
187
- venue = desired
188
- if venue <= 0:
189
- venue = desired
190
- return max(1, min(int(desired), venue))