Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/palette.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@
## 2024-05-24 - Interactive Path Completion in CLI
**Learning:** When asking for filesystem paths in the CLI, standard text inputs lead to typos and user frustration. Using specialized path inputs with auto-completion significantly improves the installation experience.
**Action:** Always use specialized path input widgets (like `questionary.path` with `only_directories=True`) instead of generic text inputs when prompting users for file or directory locations.

## 2024-05-18 - Visual Feedback for Blocking CLI Operations
**Learning:** Users perceive frozen or slow CLI applications as broken. During operations that require network requests or blocking subprocesses, providing immediate visual feedback is crucial to UX.
**Action:** Wrap blocking operations (like API calls or subprocesses) in `rich.console.status("...", spinner="dots")` context managers to display a loading spinner.
51 changes: 27 additions & 24 deletions src/ledgermind/server/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,9 +328,6 @@ def init_project(path: str):
continue

# Test model availability via API call
global_console.print(
f"Validating model [bold cyan]{enrichment_model}[/bold cyan] via OpenRouter API..."
)
try:
import httpx

Expand All @@ -346,17 +343,21 @@ def init_project(path: str):
"max_tokens": 10,
}

response = httpx.post(
"https://openrouter.ai/api/v1/chat/completions",
headers={
"Authorization": f"Bearer {openrouter_api_key}",
"Content-Type": "application/json",
"HTTP-Referer": "https://github.com/sl4m3/ledgermind",
"X-Title": "LedgerMind Setup",
},
json=test_payload,
timeout=60,
)
with global_console.status(
f"Validating model [bold cyan]{enrichment_model}[/bold cyan] via OpenRouter API...",
spinner="dots"
):
response = httpx.post(
"https://openrouter.ai/api/v1/chat/completions",
headers={
"Authorization": f"Bearer {openrouter_api_key}",
"Content-Type": "application/json",
"HTTP-Referer": "https://github.com/sl4m3/ledgermind",
"X-Title": "LedgerMind Setup",
},
json=test_payload,
timeout=60,
)

if response.status_code == 200:
result = response.json()
Expand Down Expand Up @@ -438,9 +439,6 @@ def init_project(path: str):
break

# Validation
global_console.print(
f"Validating model [bold cyan]{enrichment_model}[/bold cyan] via {client}..."
)
try:
import subprocess
import shutil
Expand Down Expand Up @@ -478,7 +476,11 @@ def init_project(path: str):
]

# We use a longer timeout for validation because APIs can be slow
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60) # nosec B603
with global_console.status(
f"Validating model [bold cyan]{enrichment_model}[/bold cyan] via {client}...",
spinner="dots"
):
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60) # nosec B603
if result.returncode == 0:
global_console.print(
f"[green]βœ“ Model {enrichment_model} is available and responsive.[/green]"
Expand Down Expand Up @@ -556,9 +558,6 @@ def init_project(path: str):
break

# Validate model with test request
global_console.print(
f"Validating model [bold cyan]{aistudio_model}[/bold cyan] via Google AI Studio..."
)
try:
import requests

Expand All @@ -571,9 +570,13 @@ def init_project(path: str):
},
}

response = requests.post(
api_url, params={"key": api_key}, json=test_body, timeout=30
)
with global_console.status(
f"Validating model [bold cyan]{aistudio_model}[/bold cyan] via Google AI Studio...",
spinner="dots"
):
response = requests.post(
api_url, params={"key": api_key}, json=test_body, timeout=30
)

if response.status_code == 200:
result = response.json()
Expand Down
Loading