hyper-sentinel 2.3.1__tar.gz → 2.3.3__tar.gz

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 (18) hide show
  1. {hyper_sentinel-2.3.1/src/hyper_sentinel.egg-info → hyper_sentinel-2.3.3}/PKG-INFO +1 -1
  2. {hyper_sentinel-2.3.1 → hyper_sentinel-2.3.3}/pyproject.toml +1 -1
  3. {hyper_sentinel-2.3.1 → hyper_sentinel-2.3.3/src/hyper_sentinel.egg-info}/PKG-INFO +1 -1
  4. {hyper_sentinel-2.3.1 → hyper_sentinel-2.3.3}/src/sentinel/__init__.py +1 -1
  5. {hyper_sentinel-2.3.1 → hyper_sentinel-2.3.3}/src/sentinel/cli.py +70 -43
  6. {hyper_sentinel-2.3.1 → hyper_sentinel-2.3.3}/LICENSE +0 -0
  7. {hyper_sentinel-2.3.1 → hyper_sentinel-2.3.3}/README.md +0 -0
  8. {hyper_sentinel-2.3.1 → hyper_sentinel-2.3.3}/setup.cfg +0 -0
  9. {hyper_sentinel-2.3.1 → hyper_sentinel-2.3.3}/src/hyper_sentinel.egg-info/SOURCES.txt +0 -0
  10. {hyper_sentinel-2.3.1 → hyper_sentinel-2.3.3}/src/hyper_sentinel.egg-info/dependency_links.txt +0 -0
  11. {hyper_sentinel-2.3.1 → hyper_sentinel-2.3.3}/src/hyper_sentinel.egg-info/entry_points.txt +0 -0
  12. {hyper_sentinel-2.3.1 → hyper_sentinel-2.3.3}/src/hyper_sentinel.egg-info/requires.txt +0 -0
  13. {hyper_sentinel-2.3.1 → hyper_sentinel-2.3.3}/src/hyper_sentinel.egg-info/top_level.txt +0 -0
  14. {hyper_sentinel-2.3.1 → hyper_sentinel-2.3.3}/src/sentinel/client.py +0 -0
  15. {hyper_sentinel-2.3.1 → hyper_sentinel-2.3.3}/src/sentinel/exceptions.py +0 -0
  16. {hyper_sentinel-2.3.1 → hyper_sentinel-2.3.3}/src/sentinel/py.typed +0 -0
  17. {hyper_sentinel-2.3.1 → hyper_sentinel-2.3.3}/tests/test_client.py +0 -0
  18. {hyper_sentinel-2.3.1 → hyper_sentinel-2.3.3}/tests/test_integration.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyper-sentinel
3
- Version: 2.3.1
3
+ Version: 2.3.3
4
4
  Summary: Python SDK for Sentinel — 80+ crypto trading, AI, and market intelligence tools. Free access, usage-based fees.
5
5
  Author-email: Sentinel Labs <dev@hyper-sentinel.com>
6
6
  License-Expression: AGPL-3.0-only
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "hyper-sentinel"
7
- version = "2.3.1"
7
+ version = "2.3.3"
8
8
  description = "Python SDK for Sentinel — 80+ crypto trading, AI, and market intelligence tools. Free access, usage-based fees."
9
9
  readme = "README.md"
10
10
  license = "AGPL-3.0-only"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyper-sentinel
3
- Version: 2.3.1
3
+ Version: 2.3.3
4
4
  Summary: Python SDK for Sentinel — 80+ crypto trading, AI, and market intelligence tools. Free access, usage-based fees.
5
5
  Author-email: Sentinel Labs <dev@hyper-sentinel.com>
6
6
  License-Expression: AGPL-3.0-only
@@ -21,7 +21,7 @@ from sentinel.exceptions import (
21
21
  ToolNotFoundError,
22
22
  )
23
23
 
24
- __version__ = "2.3.0"
24
+ __version__ = "2.3.3"
25
25
  __all__ = [
26
26
  "SentinelClient",
27
27
  "SentinelError",
@@ -161,8 +161,27 @@ def _test_gateway(api_key: str) -> dict | None:
161
161
 
162
162
  def _step_ai_key(config: dict) -> dict:
163
163
  """Step 1: AI Provider key (required)."""
164
+ # If already configured, show current status and offer to reconfigure
165
+ existing_key = config.get("ai_key", "")
166
+ existing_provider = config.get("ai_provider", "")
167
+ if existing_key and existing_provider:
168
+ detected = _detect_provider(existing_key)
169
+ if detected:
170
+ _, label, emoji = detected
171
+ masked = existing_key[:12] + "..." + existing_key[-4:]
172
+ console.print(f" [s.cyan]✓ Already configured:[/] {emoji} {label}")
173
+ console.print(f" [s.dim]Key: {masked}[/]\n")
174
+ try:
175
+ reconfigure = console.input(" [s.dim]Reconfigure? (y/N):[/] ").strip().lower()
176
+ except (EOFError, KeyboardInterrupt):
177
+ console.print("\n"); return config
178
+ if reconfigure != "y":
179
+ console.print(" [s.dim]Keeping existing key.\n[/]")
180
+ return config
181
+ console.print()
182
+
164
183
  step = Text()
165
- step.append("Step 1 — AI Provider ", style="bold white")
184
+ step.append("AI Provider ", style="bold white")
166
185
  step.append("(required)", style="s.gold")
167
186
  console.print(Panel(step, border_style="s.border", box=box.HORIZONTALS))
168
187
 
@@ -189,7 +208,7 @@ def _step_ai_key(config: dict) -> dict:
189
208
  provider_id, label, emoji = detected
190
209
  config["ai_key"] = key
191
210
  config["ai_provider"] = provider_id
192
- console.print(f"\n [s.green]Detected: {emoji} {label}[/]")
211
+ console.print(f"\n [s.cyan]Detected: {emoji} {label}[/]")
193
212
 
194
213
  # Register with gateway (fast — 5s timeout, never blocks)
195
214
  console.print(" [s.dim]Connecting to Sentinel gateway...[/]", end=" ")
@@ -204,7 +223,7 @@ def _step_ai_key(config: dict) -> dict:
204
223
  else:
205
224
  console.print("[s.cyan]✓ Account created[/]")
206
225
  else:
207
- console.print("[s.cyan]✓ Key saved[/] [s.dim](gateway will sync on first use)[/]")
226
+ console.print("[s.cyan]✓ Key saved[/]")
208
227
  config["tier"] = "free"
209
228
 
210
229
  console.print(f" [s.dim]Saved to ~/.sentinel/config[/]\n")
@@ -309,48 +328,43 @@ def _show_completion(config: dict):
309
328
  tier = config.get("tier", "free")
310
329
  tier_info = TIER_INFO.get(tier, TIER_INFO["free"])
311
330
 
331
+ # Detect provider for display
332
+ provider = config.get("ai_provider", "unknown")
333
+ detected = _detect_provider(config.get("ai_key", ""))
334
+ provider_display = f"{detected[2]} {detected[1]}" if detected else provider
335
+
312
336
  # Account summary
313
- acct = Table(
314
- show_header=False, box=None, padding=(0, 1),
315
- )
337
+ acct = Table(show_header=False, box=None, padding=(0, 1))
316
338
  acct.add_column("", style="bold white", min_width=18)
317
339
  acct.add_column("", min_width=40)
318
340
 
319
- sentinel_key = config.get("sentinel_api_key", "")
320
- key_display = sentinel_key[:20] + "..." if sentinel_key else "not set"
321
- acct.add_row("Sentinel Key", f"[s.green]{key_display}[/]")
322
- acct.add_row("Provider", f"[s.green]{config.get('ai_provider', 'unknown')}[/]")
323
- acct.add_row("Tier", f"[s.green]{tier_info['label']}[/] [s.dim]({tier_info['price']})[/]")
324
- acct.add_row("Rate Limit", f"[s.green]{tier_info['rate']}[/]")
341
+ acct.add_row("Provider", f"[s.cyan]{provider_display}[/]")
342
+ acct.add_row("Tier", f"[s.cyan]{tier_info['label']}[/] [s.dim]({tier_info['price']})[/]")
343
+ acct.add_row("Rate Limit", f"[s.cyan]{tier_info['rate']}[/]")
325
344
  acct.add_row("LLM Markup", f"{tier_info['llm']}")
326
345
  acct.add_row("Trade Fees", f"maker {tier_info['maker']} / taker {tier_info['taker']}")
327
346
  acct.add_row("Config", f"[s.dim]~/.sentinel/config[/]")
328
347
 
329
348
  console.print(Panel(
330
349
  acct,
331
- title="[s.green]✅ Setup Complete[/]",
350
+ title="[s.cyan]✅ Setup Complete[/]",
332
351
  title_align="left",
333
- border_style="s.green",
352
+ border_style="s.cyan",
334
353
  padding=(1, 2),
335
354
  ))
336
355
 
337
- # Available add commands
356
+ # Next steps menu
338
357
  console.print()
339
- console.print(" [bold]Add more services:[/]")
358
+ console.print(" [bold]Next steps:[/]")
340
359
  cmds = Table(show_header=False, box=None, padding=(0, 1))
341
- cmds.add_column("Command", style="s.green.bold")
360
+ cmds.add_column("Command", style="s.cyan.bold")
342
361
  cmds.add_column("Description", style="s.dim")
343
- cmds.add_row(" sentinel add y2", "Y2 news intelligence + AI recaps")
344
- cmds.add_row(" sentinel add x", "X (Twitter) tweets & sentiment")
345
- cmds.add_row(" sentinel add fred", "FRED economic data (GDP, CPI, rates)")
346
- cmds.add_row(" sentinel add elfa", "Elfa AI trending tokens + social")
362
+ cmds.add_row(" sentinel status", "View full dashboard")
363
+ cmds.add_row(" sentinel test", "Smoke test (auth + BTC price)")
364
+ cmds.add_row(" sentinel add", "Add data sources & trading venues")
365
+ cmds.add_row(" sentinel wallet", "Manage wallets (SOL/ETH)")
366
+ cmds.add_row(" sentinel help", "Full command reference")
347
367
  console.print(cmds)
348
-
349
- console.print()
350
- console.print(" [bold]Quick test:[/]")
351
- console.print(' [s.dim]python -c "from sentinel import SentinelClient; c = SentinelClient(); print(c.get_crypto_price(\'bitcoin\'))"[/]')
352
- console.print()
353
- console.print(" [bold]Or run:[/] [s.green.bold]sentinel test[/]")
354
368
  console.print()
355
369
 
356
370
 
@@ -529,6 +543,8 @@ def _show_status():
529
543
  if config.get("sentinel_api_key"):
530
544
  key_preview = config["sentinel_api_key"][:16] + "..."
531
545
  auth.add_row("🔑 API Key", f"[s.green]● {key_preview}[/]", "~/.sentinel/config")
546
+ elif config.get("ai_key"):
547
+ auth.add_row("🔑 API Key", "[s.cyan]● AI key set[/] [s.dim](gateway sync pending)[/]", "~/.sentinel/config")
532
548
  else:
533
549
  auth.add_row("🔑 API Key", "[s.dim]○ Not configured[/]", "run sentinel-setup")
534
550
 
@@ -562,7 +578,7 @@ def _show_status():
562
578
  gw.add_row("🔧 Tools", "[s.green]● 62+ registered[/]", "crypto · equities · AI · social · trading")
563
579
 
564
580
  # Test connectivity if we have a key
565
- if config.get("sentinel_api_key"):
581
+ if config.get("sentinel_api_key") or config.get("ai_key"):
566
582
  gw.add_row("📶 Status", "[s.dim]run 'sentinel test' to verify[/]", "")
567
583
  else:
568
584
  gw.add_row("📶 Status", "[s.dim]○ Not authenticated[/]", "run sentinel-setup")
@@ -662,11 +678,29 @@ def _run_test():
662
678
  padding=(0, 3),
663
679
  ))
664
680
 
665
- if not config.get("sentinel_api_key"):
681
+ if not config.get("sentinel_api_key") and not config.get("ai_key"):
666
682
  console.print(" [s.error]✗ No API key found[/] — run [bold]sentinel-setup[/] first.\n")
667
683
  return
668
684
 
669
- api_key = config["sentinel_api_key"]
685
+ # If we have ai_key but no sentinel_api_key, try to register now
686
+ api_key = config.get("sentinel_api_key", "")
687
+ if not api_key and config.get("ai_key"):
688
+ console.print(" [s.dim]Registering with gateway...[/]", end=" ")
689
+ result = _register_with_gateway(config["ai_key"])
690
+ if result.get("api_key"):
691
+ api_key = result["api_key"]
692
+ config["sentinel_api_key"] = api_key
693
+ config["user_id"] = result.get("user_id", "")
694
+ config["tier"] = result.get("tier", "free")
695
+ _save_config(config)
696
+ console.print("[s.cyan]✓[/]")
697
+ else:
698
+ console.print("[s.dim]gateway unavailable — test may fail[/]")
699
+
700
+ if not api_key:
701
+ console.print(" [s.error]✗ Could not obtain API key from gateway.[/]\n")
702
+ return
703
+
670
704
  key_preview = api_key[:16] + "..."
671
705
  console.print(f" [s.dim]Key: {key_preview}[/]")
672
706
  console.print(f" [s.dim]Gateway: {GATEWAY_URL}[/]")
@@ -683,7 +717,7 @@ def _run_test():
683
717
  import httpx
684
718
  client = httpx.Client(
685
719
  base_url=GATEWAY_URL,
686
- timeout=30.0,
720
+ timeout=10.0,
687
721
  headers={"X-API-Key": api_key, "Content-Type": "application/json"},
688
722
  )
689
723
 
@@ -956,7 +990,7 @@ def _show_help():
956
990
  def _handle_upgrade(plan: str = "pro"):
957
991
  """Open Stripe checkout for tier upgrade."""
958
992
  config = _load_config()
959
- if not config.get("sentinel_api_key"):
993
+ if not config.get("sentinel_api_key") and not config.get("ai_key"):
960
994
  console.print(" [s.error]✗ Not authenticated[/] — run [bold]sentinel-setup[/] first.\n")
961
995
  return
962
996
  console.print(f"\n [s.magenta]💎 Upgrading to {plan.title()}...[/]")
@@ -978,10 +1012,12 @@ def _handle_upgrade(plan: str = "pro"):
978
1012
  def _show_billing():
979
1013
  """Show billing status from the gateway."""
980
1014
  config = _load_config()
981
- if not config.get("sentinel_api_key"):
1015
+ if not config.get("sentinel_api_key") and not config.get("ai_key"):
982
1016
  console.print(" [s.error]✗ Not authenticated[/] — run [bold]sentinel-setup[/] first.\n")
983
1017
  return
984
1018
  console.print()
1019
+ tier = config.get("tier", "free")
1020
+ t_info = TIER_INFO.get(tier, TIER_INFO["free"])
985
1021
  try:
986
1022
  from sentinel import SentinelClient
987
1023
  data = SentinelClient().billing_status()
@@ -1013,7 +1049,7 @@ def _show_billing():
1013
1049
  def _show_tools():
1014
1050
  """List all tools from the gateway."""
1015
1051
  config = _load_config()
1016
- if not config.get("sentinel_api_key"):
1052
+ if not config.get("sentinel_api_key") and not config.get("ai_key"):
1017
1053
  console.print(" [s.error]✗ Not authenticated[/] — run [bold]sentinel-setup[/] first.\n")
1018
1054
  return
1019
1055
  console.print()
@@ -1048,15 +1084,6 @@ def setup():
1048
1084
  config = _step_ai_key(config)
1049
1085
  _save_config(config)
1050
1086
 
1051
- config = _step_hyperliquid(config)
1052
- _save_config(config)
1053
-
1054
- config = _step_polymarket(config)
1055
- _save_config(config)
1056
-
1057
- config = _step_aster(config)
1058
- _save_config(config)
1059
-
1060
1087
  _show_completion(config)
1061
1088
 
1062
1089
 
File without changes
File without changes
File without changes