loreguard-cli 0.12.0__tar.gz → 0.12.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.
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/PKG-INFO +1 -1
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/pyproject.toml +1 -1
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/screens/main.py +26 -2
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/screens/running.py +19 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/widgets/npc_chat.py +12 -4
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/wizard.py +1 -1
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/uv.lock +1 -1
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/.claude/skills/llama-cpp-troubleshooting/SKILL.md +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/.env.example +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/.github/workflows/release.yml +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/.gitignore +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/LICENSE +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/README.md +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/THIRD_PARTY_NOTICES.md +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/scripts/build.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/sdk/csharp/LoreguardSDK.cs +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/sdk/gdscript/LoreguardSDK.gd +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/sdk/javascript/loreguard-sdk.js +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/sdk/python/loreguard_sdk.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/__init__.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/__main__.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/chunk_detector.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/cli.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/config.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/dialogue_act_classifier.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/hf_discovery.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/http_server.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/intent_classifier.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/llama_server.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/llm.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/main.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/models_registry.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/nli.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/npc_chat.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/runtime.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/steam.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/term_ui.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/__init__.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/app.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/modals/__init__.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/modals/auth_menu.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/modals/npc_chat.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/modals/token_input.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/modals/unified_palette.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/screens/__init__.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/screens/auth.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/screens/model_select.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/screens/nli_setup.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/styles.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/widgets/__init__.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/widgets/banner.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/widgets/footer.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/widgets/hardware_info.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/widgets/server_monitor.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tui/widgets/status_panel.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/src/tunnel.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/templates/llama31-no-tools.jinja +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/tests/test_nli_hhem.py +0 -0
- {loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/tests/test_websocket_timeout.py +0 -0
|
@@ -580,6 +580,28 @@ class MainScreen(Screen):
|
|
|
580
580
|
self._log(f"Dialogue act classifier error: {e}", "error")
|
|
581
581
|
dialogue_act_classifier = None
|
|
582
582
|
|
|
583
|
+
# Initialize chunk detector (ADR-0023) - shares DeBERTa model with intent classifier
|
|
584
|
+
chunk_detector = None
|
|
585
|
+
try:
|
|
586
|
+
from ...chunk_detector import ChunkDetector
|
|
587
|
+
|
|
588
|
+
chunk_detector = ChunkDetector()
|
|
589
|
+
if intent_classifier is not None and intent_classifier._classifier is not None:
|
|
590
|
+
chunk_detector.set_classifier(intent_classifier._classifier)
|
|
591
|
+
self._log("Chunk detector ready (shared model)", "success")
|
|
592
|
+
else:
|
|
593
|
+
loop = asyncio.get_event_loop()
|
|
594
|
+
with concurrent.futures.ThreadPoolExecutor() as pool:
|
|
595
|
+
with suppress_external_output():
|
|
596
|
+
if await loop.run_in_executor(pool, chunk_detector.load_model):
|
|
597
|
+
self._log(f"Chunk detector ready ({chunk_detector.device})", "success")
|
|
598
|
+
else:
|
|
599
|
+
self._log("Chunk detector failed to load", "warning")
|
|
600
|
+
chunk_detector = None
|
|
601
|
+
except Exception as e:
|
|
602
|
+
self._log(f"Chunk detector error: {e}", "error")
|
|
603
|
+
chunk_detector = None
|
|
604
|
+
|
|
583
605
|
self._update_status("Connecting to backend...", log=False)
|
|
584
606
|
self._log("Connecting to Loreguard backend...")
|
|
585
607
|
|
|
@@ -628,6 +650,7 @@ class MainScreen(Screen):
|
|
|
628
650
|
nli_service=nli_service,
|
|
629
651
|
intent_classifier=intent_classifier,
|
|
630
652
|
dialogue_act_classifier=dialogue_act_classifier,
|
|
653
|
+
chunk_detector=chunk_detector,
|
|
631
654
|
log_callback=log_callback,
|
|
632
655
|
max_retries=0, # Single try, no retries
|
|
633
656
|
)
|
|
@@ -641,11 +664,12 @@ class MainScreen(Screen):
|
|
|
641
664
|
|
|
642
665
|
# Wire up pass update callback to chat widget (for verbose mode)
|
|
643
666
|
def on_pass_update(payload: dict) -> None:
|
|
667
|
+
log.debug(f"tunnel on_pass_update callback fired, payload keys: {list(payload.keys()) if payload else 'None'}")
|
|
644
668
|
try:
|
|
645
669
|
chat = self.query_one(NPCChat)
|
|
646
670
|
chat.on_pass_update(payload)
|
|
647
|
-
except Exception:
|
|
648
|
-
|
|
671
|
+
except Exception as e:
|
|
672
|
+
log.debug(f"tunnel on_pass_update callback error: {e}")
|
|
649
673
|
|
|
650
674
|
app._tunnel.on_pass_update = on_pass_update
|
|
651
675
|
|
|
@@ -284,6 +284,24 @@ class RunningScreen(Screen):
|
|
|
284
284
|
self._log(f"Dialogue act classifier error: {e}", "error")
|
|
285
285
|
dialogue_act_classifier = None
|
|
286
286
|
|
|
287
|
+
# Initialize chunk detector (ADR-0023) - shares DeBERTa model with intent classifier
|
|
288
|
+
chunk_detector = None
|
|
289
|
+
try:
|
|
290
|
+
from ...chunk_detector import ChunkDetector
|
|
291
|
+
|
|
292
|
+
chunk_detector = ChunkDetector()
|
|
293
|
+
if intent_classifier is not None and intent_classifier._classifier is not None:
|
|
294
|
+
chunk_detector.set_classifier(intent_classifier._classifier)
|
|
295
|
+
self._log("Chunk detector ready (shared model)", "success")
|
|
296
|
+
else:
|
|
297
|
+
if await asyncio.to_thread(chunk_detector.load_model):
|
|
298
|
+
self._log(f"Chunk detector ready ({chunk_detector.device})", "success")
|
|
299
|
+
else:
|
|
300
|
+
chunk_detector = None
|
|
301
|
+
except Exception as e:
|
|
302
|
+
self._log(f"Chunk detector error: {e}", "error")
|
|
303
|
+
chunk_detector = None
|
|
304
|
+
|
|
287
305
|
# Get model ID for backend
|
|
288
306
|
model_id = app.model_path.stem
|
|
289
307
|
|
|
@@ -296,6 +314,7 @@ class RunningScreen(Screen):
|
|
|
296
314
|
nli_service=nli_service,
|
|
297
315
|
intent_classifier=intent_classifier,
|
|
298
316
|
dialogue_act_classifier=dialogue_act_classifier,
|
|
317
|
+
chunk_detector=chunk_detector,
|
|
299
318
|
log_callback=self._log,
|
|
300
319
|
)
|
|
301
320
|
self._tunnel.on_request_complete = self._on_request_complete
|
|
@@ -5,9 +5,12 @@ Uses the local proxy for NPC conversations with token streaming:
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import json
|
|
8
|
+
import logging
|
|
8
9
|
from typing import TYPE_CHECKING
|
|
9
10
|
|
|
10
11
|
import httpx
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
11
14
|
from textual.app import ComposeResult
|
|
12
15
|
from textual.containers import Vertical, Horizontal, VerticalScroll
|
|
13
16
|
from textual.widgets import Static, Input
|
|
@@ -799,11 +802,11 @@ class NPCChat(Vertical):
|
|
|
799
802
|
if self._verbose:
|
|
800
803
|
payload["verbose"] = True
|
|
801
804
|
|
|
805
|
+
local_url = get_local_proxy_url()
|
|
802
806
|
try:
|
|
803
807
|
await self._do_generate_streaming(payload, status, container)
|
|
804
808
|
return
|
|
805
809
|
except httpx.ConnectError as e:
|
|
806
|
-
local_url = get_local_proxy_url()
|
|
807
810
|
if self._verbose:
|
|
808
811
|
if local_url:
|
|
809
812
|
status.update(Text(f"Local proxy failed ({local_url}): {e}", style=FG_DIM))
|
|
@@ -812,7 +815,6 @@ class NPCChat(Vertical):
|
|
|
812
815
|
else:
|
|
813
816
|
status.update(Text("Local proxy unavailable, using cloud...", style=FG_DIM))
|
|
814
817
|
except Exception as e:
|
|
815
|
-
local_url = get_local_proxy_url()
|
|
816
818
|
if self._verbose:
|
|
817
819
|
status.update(Text(f"Local proxy error ({local_url}): {type(e).__name__}: {e}", style="#FF5555"))
|
|
818
820
|
else:
|
|
@@ -895,6 +897,9 @@ class NPCChat(Vertical):
|
|
|
895
897
|
container.scroll_end(animate=False)
|
|
896
898
|
status.update(Text(f"Streaming... ({tokens_received} tokens)", style=CYAN))
|
|
897
899
|
|
|
900
|
+
elif event_type == "pass_update":
|
|
901
|
+
self.on_pass_update(data)
|
|
902
|
+
|
|
898
903
|
elif event_type == "done":
|
|
899
904
|
final_data = data
|
|
900
905
|
speech = data.get("speech", speech)
|
|
@@ -987,15 +992,18 @@ class NPCChat(Vertical):
|
|
|
987
992
|
|
|
988
993
|
Called by the tunnel when it receives pass updates via WebSocket.
|
|
989
994
|
"""
|
|
995
|
+
logger.debug(f"on_pass_update called: verbose={self._verbose}, visible={self._visible}, payload_keys={list(payload.keys()) if payload else 'None'}")
|
|
990
996
|
if not self._verbose or not self._visible:
|
|
997
|
+
logger.debug(f"on_pass_update skipped: verbose={self._verbose}, visible={self._visible}")
|
|
991
998
|
return
|
|
992
999
|
|
|
993
1000
|
# Add pass to debug panel instead of chat
|
|
994
1001
|
try:
|
|
995
1002
|
debug_panel = self.query_one(DebugPanel)
|
|
996
1003
|
debug_panel.add_pass(payload)
|
|
997
|
-
|
|
998
|
-
|
|
1004
|
+
logger.debug(f"on_pass_update: added pass to debug panel")
|
|
1005
|
+
except Exception as e:
|
|
1006
|
+
logger.debug(f"on_pass_update exception: {e}")
|
|
999
1007
|
|
|
1000
1008
|
def action_close_chat(self) -> None:
|
|
1001
1009
|
"""Close the chat widget."""
|
|
@@ -1596,7 +1596,7 @@ async def step_start(
|
|
|
1596
1596
|
status.stop()
|
|
1597
1597
|
from .npc_chat import run_npc_chat
|
|
1598
1598
|
try:
|
|
1599
|
-
await run_npc_chat(api_token=token, tunnel=tunnel)
|
|
1599
|
+
await run_npc_chat(api_token=token, tunnel=tunnel, verbose=_verbose)
|
|
1600
1600
|
except KeyboardInterrupt:
|
|
1601
1601
|
pass
|
|
1602
1602
|
status.start()
|
{loreguard_cli-0.12.0 → loreguard_cli-0.12.2}/.claude/skills/llama-cpp-troubleshooting/SKILL.md
RENAMED
|
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
|