systemr-cli 1.0.2__tar.gz → 1.0.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.
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/PKG-INFO +1 -1
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/__init__.py +1 -1
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/cli.py +23 -6
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/commands/chat_commands.py +34 -5
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/pyproject.toml +1 -1
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/.gitignore +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/DESIGN.md +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/README.md +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/clawhub/systemr-trading/SKILL.md +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/clawhub/systemr-trading/scripts/mcp_stdio_proxy.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/__main__.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/auth.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/client.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/commands/__init__.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/commands/auth_commands.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/commands/cron_commands.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/commands/doctor_command.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/commands/eval_commands.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/commands/journal_commands.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/commands/plan_commands.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/commands/risk_commands.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/commands/scan_commands.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/commands/size_commands.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/config.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/confirmation.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/credits.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/cron.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/display/__init__.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/display/chat_renderer.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/display/formatters.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/display/tables.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/display/theme.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/hooks.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/logging.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/model_failover.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/orchestrator.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/profile.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/store.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/streaming.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/neo/types.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/__init__.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_auth.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_chat_helpers.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_chat_renderer.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_cli.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_config.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_confirmation.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_credits.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_cron.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_doctor.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_formatters.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_hooks.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_logging.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_model_failover.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_orchestrator.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_profile.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_store.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_streaming.py +0 -0
- {systemr_cli-1.0.2 → systemr_cli-1.0.3}/tests/test_types.py +0 -0
|
@@ -179,13 +179,30 @@ def setup() -> None:
|
|
|
179
179
|
console.print(f" [{WHITE}]Welcome. Let's set up your profile.[/]")
|
|
180
180
|
console.print()
|
|
181
181
|
|
|
182
|
-
style = click.prompt(click.style(" Trading style", fg="white"))
|
|
183
|
-
timeframe = click.prompt(click.style(" Timeframe", fg="white"))
|
|
184
|
-
risk_pct = click.prompt(click.style(" Max risk per trade (%)", fg="white"))
|
|
185
|
-
daily_loss = click.prompt(click.style(" Max daily loss (%)", fg="white"))
|
|
186
|
-
max_pos = click.prompt(click.style(" Max open positions", fg="white"), type=int)
|
|
187
|
-
broker = click.prompt(click.style(" Primary broker", fg="white"))
|
|
188
182
|
name = click.prompt(click.style(" Your name", fg="white"))
|
|
183
|
+
while not name.strip() or len(name.strip()) < 2:
|
|
184
|
+
print_error("Name must be at least 2 characters.")
|
|
185
|
+
name = click.prompt(click.style(" Your name", fg="white"))
|
|
186
|
+
|
|
187
|
+
style = click.prompt(click.style(" Trading style (e.g. momentum, swing, scalp)", fg="white"))
|
|
188
|
+
timeframe = click.prompt(click.style(" Timeframe (e.g. daily, 4h, 1h)", fg="white"))
|
|
189
|
+
|
|
190
|
+
risk_pct = click.prompt(
|
|
191
|
+
click.style(" Max risk per trade (%)", fg="white"),
|
|
192
|
+
type=click.FloatRange(0.1, 10.0),
|
|
193
|
+
default=1.0,
|
|
194
|
+
)
|
|
195
|
+
daily_loss = click.prompt(
|
|
196
|
+
click.style(" Max daily loss (%)", fg="white"),
|
|
197
|
+
type=click.FloatRange(0.5, 20.0),
|
|
198
|
+
default=3.0,
|
|
199
|
+
)
|
|
200
|
+
max_pos = click.prompt(
|
|
201
|
+
click.style(" Max open positions", fg="white"),
|
|
202
|
+
type=click.IntRange(1, 100),
|
|
203
|
+
default=5,
|
|
204
|
+
)
|
|
205
|
+
broker = click.prompt(click.style(" Primary broker", fg="white"))
|
|
189
206
|
|
|
190
207
|
console.print()
|
|
191
208
|
console.print(f" [{GRAY}]Any hard rules? (comma-separated, or Enter to skip)[/]")
|
|
@@ -13,6 +13,7 @@ import asyncio
|
|
|
13
13
|
import json
|
|
14
14
|
|
|
15
15
|
import click
|
|
16
|
+
import httpx
|
|
16
17
|
import structlog
|
|
17
18
|
from prompt_toolkit import PromptSession
|
|
18
19
|
from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
|
|
@@ -463,10 +464,26 @@ async def _do_chat(
|
|
|
463
464
|
})
|
|
464
465
|
|
|
465
466
|
elif event.event == "error":
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
467
|
+
raw = event.parsed.get("message", event.parsed.get("error", event.data))
|
|
468
|
+
msg = str(raw)
|
|
469
|
+
# Simplify common backend errors for users
|
|
470
|
+
if "Classification backend unavailable" in msg:
|
|
471
|
+
msg = "AI model temporarily unavailable. Try again in a moment."
|
|
472
|
+
elif "AccessDeniedException" in msg:
|
|
473
|
+
msg = "AI model access error. Contact support."
|
|
474
|
+
elif "ThrottlingException" in msg:
|
|
475
|
+
msg = "Rate limited by AI provider. Wait a moment and try again."
|
|
476
|
+
elif len(msg) > 120:
|
|
477
|
+
msg = msg[:120] + "..."
|
|
478
|
+
render_error(msg)
|
|
479
|
+
fire_hook(HookEvent.ERROR, context={"message": msg})
|
|
480
|
+
|
|
481
|
+
except httpx.ConnectError:
|
|
482
|
+
render_error("Cannot connect to System R. Check your internet connection.")
|
|
483
|
+
fire_hook(HookEvent.ERROR, context={"message": "connection_failed"})
|
|
484
|
+
except httpx.ReadTimeout:
|
|
485
|
+
render_error("Response timed out. Try again or use a simpler query.")
|
|
486
|
+
fire_hook(HookEvent.ERROR, context={"message": "read_timeout"})
|
|
470
487
|
except Exception:
|
|
471
488
|
# Fall back to blocking
|
|
472
489
|
try:
|
|
@@ -476,8 +493,20 @@ async def _do_chat(
|
|
|
476
493
|
collected_text = reply
|
|
477
494
|
render_assistant_message(reply)
|
|
478
495
|
credits.add_response(tools=1)
|
|
496
|
+
except httpx.ConnectError:
|
|
497
|
+
render_error("Cannot connect to System R. Check your internet connection.")
|
|
498
|
+
except httpx.HTTPStatusError as exc:
|
|
499
|
+
if exc.response.status_code == 401:
|
|
500
|
+
render_error("Session expired. Run `systemr login` or `systemr configure --api-key`.")
|
|
501
|
+
elif exc.response.status_code == 402:
|
|
502
|
+
render_error("Insufficient credits. Run `systemr pay` to add credits.")
|
|
503
|
+
elif exc.response.status_code == 429:
|
|
504
|
+
render_error("Rate limited. Wait a moment and try again.")
|
|
505
|
+
else:
|
|
506
|
+
render_error(f"Server error ({exc.response.status_code}). Try again.")
|
|
479
507
|
except Exception as exc:
|
|
480
|
-
render_error(
|
|
508
|
+
render_error("Something went wrong. Try again or run `systemr doctor` to check.")
|
|
509
|
+
logger.error("chat_fallback_error", error=str(exc))
|
|
481
510
|
fire_hook(HookEvent.ERROR, context={"message": str(exc)})
|
|
482
511
|
|
|
483
512
|
return collected_text
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|