hyper-sentinel 2.3.0__tar.gz → 2.3.2__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.0/src/hyper_sentinel.egg-info → hyper_sentinel-2.3.2}/PKG-INFO +1 -1
  2. {hyper_sentinel-2.3.0 → hyper_sentinel-2.3.2}/pyproject.toml +1 -1
  3. {hyper_sentinel-2.3.0 → hyper_sentinel-2.3.2/src/hyper_sentinel.egg-info}/PKG-INFO +1 -1
  4. {hyper_sentinel-2.3.0 → hyper_sentinel-2.3.2}/src/sentinel/__init__.py +1 -1
  5. {hyper_sentinel-2.3.0 → hyper_sentinel-2.3.2}/src/sentinel/cli.py +54 -56
  6. {hyper_sentinel-2.3.0 → hyper_sentinel-2.3.2}/LICENSE +0 -0
  7. {hyper_sentinel-2.3.0 → hyper_sentinel-2.3.2}/README.md +0 -0
  8. {hyper_sentinel-2.3.0 → hyper_sentinel-2.3.2}/setup.cfg +0 -0
  9. {hyper_sentinel-2.3.0 → hyper_sentinel-2.3.2}/src/hyper_sentinel.egg-info/SOURCES.txt +0 -0
  10. {hyper_sentinel-2.3.0 → hyper_sentinel-2.3.2}/src/hyper_sentinel.egg-info/dependency_links.txt +0 -0
  11. {hyper_sentinel-2.3.0 → hyper_sentinel-2.3.2}/src/hyper_sentinel.egg-info/entry_points.txt +0 -0
  12. {hyper_sentinel-2.3.0 → hyper_sentinel-2.3.2}/src/hyper_sentinel.egg-info/requires.txt +0 -0
  13. {hyper_sentinel-2.3.0 → hyper_sentinel-2.3.2}/src/hyper_sentinel.egg-info/top_level.txt +0 -0
  14. {hyper_sentinel-2.3.0 → hyper_sentinel-2.3.2}/src/sentinel/client.py +0 -0
  15. {hyper_sentinel-2.3.0 → hyper_sentinel-2.3.2}/src/sentinel/exceptions.py +0 -0
  16. {hyper_sentinel-2.3.0 → hyper_sentinel-2.3.2}/src/sentinel/py.typed +0 -0
  17. {hyper_sentinel-2.3.0 → hyper_sentinel-2.3.2}/tests/test_client.py +0 -0
  18. {hyper_sentinel-2.3.0 → hyper_sentinel-2.3.2}/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.0
3
+ Version: 2.3.2
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.0"
7
+ version = "2.3.2"
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.0
3
+ Version: 2.3.2
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.2"
25
25
  __all__ = [
26
26
  "SentinelClient",
27
27
  "SentinelError",
@@ -106,13 +106,13 @@ def _save_config(config: dict[str, Any]):
106
106
 
107
107
 
108
108
  def _register_with_gateway(ai_key: str) -> dict[str, str]:
109
- """Call POST /auth/ai-key to auto-create account."""
109
+ """Call POST /auth/ai-key to auto-create account. Fast timeout — never block setup."""
110
110
  try:
111
111
  import httpx
112
112
  resp = httpx.post(
113
113
  f"{GATEWAY_URL}/auth/ai-key",
114
114
  json={"ai_key": ai_key},
115
- timeout=30.0,
115
+ timeout=5.0,
116
116
  )
117
117
  if resp.status_code in (200, 201):
118
118
  return resp.json()
@@ -127,7 +127,7 @@ def _test_gateway(api_key: str) -> dict | None:
127
127
  import httpx
128
128
  client = httpx.Client(
129
129
  base_url=GATEWAY_URL,
130
- timeout=30.0,
130
+ timeout=5.0,
131
131
  headers={"X-API-Key": api_key, "Content-Type": "application/json"},
132
132
  )
133
133
 
@@ -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,10 +208,10 @@ 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
- # Register with gateway
195
- console.print(" [s.dim]Registering with Sentinel gateway...[/]", end=" ")
213
+ # Register with gateway (fast — 5s timeout, never blocks)
214
+ console.print(" [s.dim]Connecting to Sentinel gateway...[/]", end=" ")
196
215
  result = _register_with_gateway(key)
197
216
  if result.get("api_key"):
198
217
  config["sentinel_api_key"] = result["api_key"]
@@ -200,21 +219,12 @@ def _step_ai_key(config: dict) -> dict:
200
219
  config["tier"] = result.get("tier", "free")
201
220
  status = result.get("status", "created")
202
221
  if status == "existing":
203
- console.print("[s.green]✓ Welcome back[/]")
204
- else:
205
- console.print("[s.green]✓ Account created[/]")
206
-
207
- # Verify with a tool call
208
- console.print(" [s.dim]Testing connection...[/]", end=" ")
209
- test = _test_gateway(config["sentinel_api_key"])
210
- if test and test.get("tool_test") == "pass":
211
- console.print(f"[s.green]✓ BTC = ${test.get('btc_price', '?')}[/]")
212
- elif test:
213
- console.print("[s.yellow]⚠ Gateway up, tool test inconclusive[/]")
222
+ console.print("[s.cyan]✓ Welcome back[/]")
214
223
  else:
215
- console.print("[s.dim]skipped will verify on first API call[/]")
224
+ console.print("[s.cyan] Account created[/]")
216
225
  else:
217
- console.print("[s.dim]gateway unavailable — will retry on first API call[/]")
226
+ console.print("[s.cyan] Key saved[/]")
227
+ config["tier"] = "free"
218
228
 
219
229
  console.print(f" [s.dim]Saved to ~/.sentinel/config[/]\n")
220
230
  break
@@ -318,48 +328,43 @@ def _show_completion(config: dict):
318
328
  tier = config.get("tier", "free")
319
329
  tier_info = TIER_INFO.get(tier, TIER_INFO["free"])
320
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
+
321
336
  # Account summary
322
- acct = Table(
323
- show_header=False, box=None, padding=(0, 1),
324
- )
337
+ acct = Table(show_header=False, box=None, padding=(0, 1))
325
338
  acct.add_column("", style="bold white", min_width=18)
326
339
  acct.add_column("", min_width=40)
327
340
 
328
- sentinel_key = config.get("sentinel_api_key", "")
329
- key_display = sentinel_key[:20] + "..." if sentinel_key else "not set"
330
- acct.add_row("Sentinel Key", f"[s.green]{key_display}[/]")
331
- acct.add_row("Provider", f"[s.green]{config.get('ai_provider', 'unknown')}[/]")
332
- acct.add_row("Tier", f"[s.green]{tier_info['label']}[/] [s.dim]({tier_info['price']})[/]")
333
- 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']}[/]")
334
344
  acct.add_row("LLM Markup", f"{tier_info['llm']}")
335
345
  acct.add_row("Trade Fees", f"maker {tier_info['maker']} / taker {tier_info['taker']}")
336
346
  acct.add_row("Config", f"[s.dim]~/.sentinel/config[/]")
337
347
 
338
348
  console.print(Panel(
339
349
  acct,
340
- title="[s.green]✅ Setup Complete[/]",
350
+ title="[s.cyan]✅ Setup Complete[/]",
341
351
  title_align="left",
342
- border_style="s.green",
352
+ border_style="s.cyan",
343
353
  padding=(1, 2),
344
354
  ))
345
355
 
346
- # Available add commands
356
+ # Next steps menu
347
357
  console.print()
348
- console.print(" [bold]Add more services:[/]")
358
+ console.print(" [bold]Next steps:[/]")
349
359
  cmds = Table(show_header=False, box=None, padding=(0, 1))
350
- cmds.add_column("Command", style="s.green.bold")
360
+ cmds.add_column("Command", style="s.cyan.bold")
351
361
  cmds.add_column("Description", style="s.dim")
352
- cmds.add_row(" sentinel add y2", "Y2 news intelligence + AI recaps")
353
- cmds.add_row(" sentinel add x", "X (Twitter) tweets & sentiment")
354
- cmds.add_row(" sentinel add fred", "FRED economic data (GDP, CPI, rates)")
355
- 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")
356
367
  console.print(cmds)
357
-
358
- console.print()
359
- console.print(" [bold]Quick test:[/]")
360
- console.print(' [s.dim]python -c "from sentinel import SentinelClient; c = SentinelClient(); print(c.get_crypto_price(\'bitcoin\'))"[/]')
361
- console.print()
362
- console.print(" [bold]Or run:[/] [s.green.bold]sentinel test[/]")
363
368
  console.print()
364
369
 
365
370
 
@@ -965,7 +970,7 @@ def _show_help():
965
970
  def _handle_upgrade(plan: str = "pro"):
966
971
  """Open Stripe checkout for tier upgrade."""
967
972
  config = _load_config()
968
- if not config.get("sentinel_api_key"):
973
+ if not config.get("sentinel_api_key") and not config.get("ai_key"):
969
974
  console.print(" [s.error]✗ Not authenticated[/] — run [bold]sentinel-setup[/] first.\n")
970
975
  return
971
976
  console.print(f"\n [s.magenta]💎 Upgrading to {plan.title()}...[/]")
@@ -987,10 +992,12 @@ def _handle_upgrade(plan: str = "pro"):
987
992
  def _show_billing():
988
993
  """Show billing status from the gateway."""
989
994
  config = _load_config()
990
- if not config.get("sentinel_api_key"):
995
+ if not config.get("sentinel_api_key") and not config.get("ai_key"):
991
996
  console.print(" [s.error]✗ Not authenticated[/] — run [bold]sentinel-setup[/] first.\n")
992
997
  return
993
998
  console.print()
999
+ tier = config.get("tier", "free")
1000
+ t_info = TIER_INFO.get(tier, TIER_INFO["free"])
994
1001
  try:
995
1002
  from sentinel import SentinelClient
996
1003
  data = SentinelClient().billing_status()
@@ -1022,7 +1029,7 @@ def _show_billing():
1022
1029
  def _show_tools():
1023
1030
  """List all tools from the gateway."""
1024
1031
  config = _load_config()
1025
- if not config.get("sentinel_api_key"):
1032
+ if not config.get("sentinel_api_key") and not config.get("ai_key"):
1026
1033
  console.print(" [s.error]✗ Not authenticated[/] — run [bold]sentinel-setup[/] first.\n")
1027
1034
  return
1028
1035
  console.print()
@@ -1057,15 +1064,6 @@ def setup():
1057
1064
  config = _step_ai_key(config)
1058
1065
  _save_config(config)
1059
1066
 
1060
- config = _step_hyperliquid(config)
1061
- _save_config(config)
1062
-
1063
- config = _step_polymarket(config)
1064
- _save_config(config)
1065
-
1066
- config = _step_aster(config)
1067
- _save_config(config)
1068
-
1069
1067
  _show_completion(config)
1070
1068
 
1071
1069
 
File without changes
File without changes
File without changes