dtSpark 1.1.0a3__py3-none-any.whl → 1.1.0a7__py3-none-any.whl
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.
- dtSpark/_version.txt +1 -1
- dtSpark/aws/authentication.py +1 -1
- dtSpark/aws/bedrock.py +238 -239
- dtSpark/aws/costs.py +9 -5
- dtSpark/aws/pricing.py +25 -21
- dtSpark/cli_interface.py +77 -68
- dtSpark/conversation_manager.py +54 -47
- dtSpark/core/application.py +114 -91
- dtSpark/core/context_compaction.py +241 -226
- dtSpark/daemon/__init__.py +36 -22
- dtSpark/daemon/action_monitor.py +46 -17
- dtSpark/daemon/daemon_app.py +126 -104
- dtSpark/daemon/daemon_manager.py +59 -23
- dtSpark/daemon/pid_file.py +3 -2
- dtSpark/database/autonomous_actions.py +3 -0
- dtSpark/database/credential_prompt.py +52 -54
- dtSpark/files/manager.py +6 -12
- dtSpark/limits/__init__.py +1 -1
- dtSpark/limits/tokens.py +2 -2
- dtSpark/llm/anthropic_direct.py +246 -141
- dtSpark/llm/ollama.py +3 -1
- dtSpark/mcp_integration/manager.py +4 -4
- dtSpark/mcp_integration/tool_selector.py +83 -77
- dtSpark/resources/config.yaml.template +11 -0
- dtSpark/safety/patterns.py +45 -46
- dtSpark/safety/prompt_inspector.py +8 -1
- dtSpark/scheduler/creation_tools.py +273 -181
- dtSpark/scheduler/executor.py +503 -221
- dtSpark/tools/builtin.py +70 -53
- dtSpark/web/endpoints/autonomous_actions.py +12 -9
- dtSpark/web/endpoints/chat.py +8 -6
- dtSpark/web/endpoints/conversations.py +18 -9
- dtSpark/web/endpoints/main_menu.py +132 -105
- dtSpark/web/endpoints/streaming.py +2 -2
- dtSpark/web/server.py +70 -5
- dtSpark/web/ssl_utils.py +3 -3
- dtSpark/web/static/css/dark-theme.css +8 -29
- dtSpark/web/static/js/chat.js +6 -8
- dtSpark/web/static/js/main.js +8 -8
- dtSpark/web/static/js/sse-client.js +130 -122
- dtSpark/web/templates/actions.html +5 -5
- dtSpark/web/templates/base.html +15 -0
- dtSpark/web/templates/chat.html +10 -10
- dtSpark/web/templates/conversations.html +6 -2
- dtSpark/web/templates/goodbye.html +2 -2
- dtSpark/web/templates/main_menu.html +19 -17
- dtSpark/web/web_interface.py +2 -2
- {dtspark-1.1.0a3.dist-info → dtspark-1.1.0a7.dist-info}/METADATA +9 -2
- dtspark-1.1.0a7.dist-info/RECORD +96 -0
- dtspark-1.1.0a3.dist-info/RECORD +0 -96
- {dtspark-1.1.0a3.dist-info → dtspark-1.1.0a7.dist-info}/WHEEL +0 -0
- {dtspark-1.1.0a3.dist-info → dtspark-1.1.0a7.dist-info}/entry_points.txt +0 -0
- {dtspark-1.1.0a3.dist-info → dtspark-1.1.0a7.dist-info}/licenses/LICENSE +0 -0
- {dtspark-1.1.0a3.dist-info → dtspark-1.1.0a7.dist-info}/top_level.txt +0 -0
dtSpark/core/application.py
CHANGED
|
@@ -84,6 +84,16 @@ def copy_to_clipboard(text: str) -> bool:
|
|
|
84
84
|
logging.error(f"Failed to copy to clipboard: {e}")
|
|
85
85
|
return False
|
|
86
86
|
|
|
87
|
+
# Common string constants (SonarCloud S1192)
|
|
88
|
+
_SETTING_BEDROCK_COST_TRACKING = 'llm_providers.aws_bedrock.cost_tracking.enabled'
|
|
89
|
+
_SETTING_COST_TRACKING = 'aws.cost_tracking.enabled'
|
|
90
|
+
_SETTING_OLLAMA_ENABLED = 'llm_providers.ollama.enabled'
|
|
91
|
+
_DEFAULT_RUNNING_DIR = "./running"
|
|
92
|
+
_PROMPT_ACCESS_MODE = "Select access mode"
|
|
93
|
+
_MSG_NO_MODELS = "No models available"
|
|
94
|
+
_MSG_MANAGED_CONVERSATION = "This conversation is managed by configuration"
|
|
95
|
+
_MSG_DELETE_CANCELLED = "Delete operation cancelled"
|
|
96
|
+
|
|
87
97
|
class AWSBedrockCLI(AbstractApp):
|
|
88
98
|
def __init__(self):
|
|
89
99
|
super().__init__(short_name=agent_type(), full_name=full_name(), version=version(),
|
|
@@ -371,10 +381,12 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
371
381
|
aws_session_token = self.settings.get('aws.session_token', None)
|
|
372
382
|
|
|
373
383
|
# Configure CLI cost tracking display
|
|
374
|
-
cost_tracking_enabled = self._get_nested_setting(
|
|
384
|
+
cost_tracking_enabled = self._get_nested_setting(_SETTING_BEDROCK_COST_TRACKING, None)
|
|
375
385
|
if cost_tracking_enabled is None:
|
|
376
|
-
cost_tracking_enabled = self.settings.get(
|
|
386
|
+
cost_tracking_enabled = self.settings.get(_SETTING_COST_TRACKING, False)
|
|
377
387
|
self.cli.cost_tracking_enabled = cost_tracking_enabled
|
|
388
|
+
self.cli.actions_enabled = self._get_nested_setting('autonomous_actions.enabled', False)
|
|
389
|
+
self.cli.new_conversations_allowed = self._get_nested_setting('predefined_conversations.allow_new_conversations', True)
|
|
378
390
|
|
|
379
391
|
progress.update(task_config, advance=100)
|
|
380
392
|
|
|
@@ -391,7 +403,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
391
403
|
# Handle missing or various value types
|
|
392
404
|
if aws_enabled_raw is None:
|
|
393
405
|
# Setting not found via any method - check if other providers are enabled
|
|
394
|
-
ollama_check = self._get_nested_setting(
|
|
406
|
+
ollama_check = self._get_nested_setting(_SETTING_OLLAMA_ENABLED, False)
|
|
395
407
|
anthropic_check = self._get_nested_setting('llm_providers.anthropic.enabled', False)
|
|
396
408
|
if ollama_check or anthropic_check:
|
|
397
409
|
# Other providers configured, don't default to AWS
|
|
@@ -432,7 +444,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
432
444
|
self.cli.print_warning("Failed to authenticate with AWS Bedrock")
|
|
433
445
|
|
|
434
446
|
# Check if Ollama is available as fallback
|
|
435
|
-
ollama_enabled = self._get_nested_setting(
|
|
447
|
+
ollama_enabled = self._get_nested_setting(_SETTING_OLLAMA_ENABLED, False)
|
|
436
448
|
if not ollama_enabled:
|
|
437
449
|
self.cli.print_error("AWS authentication required (Ollama not configured)")
|
|
438
450
|
self.cli.print_info(f"Run: aws sso login --profile {aws_profile}")
|
|
@@ -457,7 +469,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
457
469
|
progress.update(task_llm, advance=20, description="[cyan]Checking Ollama...")
|
|
458
470
|
|
|
459
471
|
# Check Ollama configuration
|
|
460
|
-
ollama_enabled = self._get_nested_setting(
|
|
472
|
+
ollama_enabled = self._get_nested_setting(_SETTING_OLLAMA_ENABLED, False)
|
|
461
473
|
if ollama_enabled:
|
|
462
474
|
try:
|
|
463
475
|
ollama_url = self._get_nested_setting(
|
|
@@ -529,9 +541,9 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
529
541
|
|
|
530
542
|
# Task 3.5: Retrieve Bedrock cost information (silently, display later)
|
|
531
543
|
# Only if cost tracking is enabled in configuration
|
|
532
|
-
cost_tracking_enabled = self._get_nested_setting(
|
|
544
|
+
cost_tracking_enabled = self._get_nested_setting(_SETTING_BEDROCK_COST_TRACKING, None)
|
|
533
545
|
if cost_tracking_enabled is None:
|
|
534
|
-
cost_tracking_enabled = self.settings.get(
|
|
546
|
+
cost_tracking_enabled = self.settings.get(_SETTING_COST_TRACKING, False)
|
|
535
547
|
if cost_tracking_enabled and self.authenticator:
|
|
536
548
|
task_costs = progress.add_task("[cyan]Retrieving usage costs...", total=100)
|
|
537
549
|
self.bedrock_costs = None
|
|
@@ -796,77 +808,88 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
796
808
|
)
|
|
797
809
|
progress.update(task_conv, advance=100)
|
|
798
810
|
|
|
799
|
-
# Task 7: Initialise autonomous action scheduler
|
|
811
|
+
# Task 7: Initialise autonomous action scheduler (if enabled)
|
|
812
|
+
self.actions_enabled = self._get_nested_setting('autonomous_actions.enabled', False)
|
|
813
|
+
self.new_conversations_allowed = self._get_nested_setting('predefined_conversations.allow_new_conversations', True)
|
|
800
814
|
task_scheduler = progress.add_task("[cyan]Initialising action scheduler...", total=100)
|
|
801
|
-
try:
|
|
802
|
-
from dtSpark.scheduler import (
|
|
803
|
-
ActionSchedulerManager,
|
|
804
|
-
ActionExecutionQueue,
|
|
805
|
-
ActionExecutor
|
|
806
|
-
)
|
|
807
815
|
|
|
808
|
-
|
|
809
|
-
|
|
816
|
+
if not self.actions_enabled:
|
|
817
|
+
logging.info("Autonomous actions are disabled via configuration")
|
|
818
|
+
self.action_scheduler = None
|
|
819
|
+
self.execution_queue = None
|
|
820
|
+
self.action_executor = None
|
|
821
|
+
self.daemon_is_running = False
|
|
822
|
+
progress.update(task_scheduler, advance=100)
|
|
823
|
+
else:
|
|
824
|
+
try:
|
|
825
|
+
from dtSpark.scheduler import (
|
|
826
|
+
ActionSchedulerManager,
|
|
827
|
+
ActionExecutionQueue,
|
|
828
|
+
ActionExecutor
|
|
829
|
+
)
|
|
810
830
|
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
if self.mcp_manager:
|
|
814
|
-
def get_tools_func():
|
|
815
|
-
import asyncio
|
|
816
|
-
loop = getattr(self.mcp_manager, '_initialization_loop', None)
|
|
817
|
-
if loop and not loop.is_closed():
|
|
818
|
-
return loop.run_until_complete(self.mcp_manager.list_all_tools())
|
|
819
|
-
return []
|
|
820
|
-
|
|
821
|
-
self.action_executor = ActionExecutor(
|
|
822
|
-
database=self.database,
|
|
823
|
-
llm_manager=self.llm_manager,
|
|
824
|
-
mcp_manager=self.mcp_manager,
|
|
825
|
-
get_tools_func=get_tools_func,
|
|
826
|
-
config=config_for_manager
|
|
827
|
-
)
|
|
831
|
+
# Get database path for scheduler job store
|
|
832
|
+
db_path = self.database.db_path or ':memory:'
|
|
828
833
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
834
|
+
# Create executor with LLM manager and optional MCP manager
|
|
835
|
+
get_tools_func = None
|
|
836
|
+
if self.mcp_manager:
|
|
837
|
+
def get_tools_func():
|
|
838
|
+
import asyncio
|
|
839
|
+
loop = getattr(self.mcp_manager, '_initialization_loop', None)
|
|
840
|
+
if loop and not loop.is_closed():
|
|
841
|
+
return loop.run_until_complete(self.mcp_manager.list_all_tools())
|
|
842
|
+
return []
|
|
843
|
+
|
|
844
|
+
self.action_executor = ActionExecutor(
|
|
845
|
+
database=self.database,
|
|
846
|
+
llm_manager=self.llm_manager,
|
|
847
|
+
mcp_manager=self.mcp_manager,
|
|
848
|
+
get_tools_func=get_tools_func,
|
|
849
|
+
config=config_for_manager
|
|
850
|
+
)
|
|
833
851
|
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
execution_callback=lambda action_id, user_guid: self.execution_queue.enqueue(
|
|
838
|
-
action_id, user_guid, is_manual=False
|
|
852
|
+
# Create execution queue
|
|
853
|
+
self.execution_queue = ActionExecutionQueue(
|
|
854
|
+
executor_func=self.action_executor.execute
|
|
839
855
|
)
|
|
840
|
-
)
|
|
841
856
|
|
|
842
|
-
|
|
843
|
-
|
|
857
|
+
# Create scheduler manager
|
|
858
|
+
self.action_scheduler = ActionSchedulerManager(
|
|
859
|
+
db_path=db_path,
|
|
860
|
+
execution_callback=lambda action_id, user_guid: self.execution_queue.enqueue(
|
|
861
|
+
action_id, user_guid, is_manual=False
|
|
862
|
+
)
|
|
863
|
+
)
|
|
844
864
|
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
self.action_scheduler.initialise()
|
|
848
|
-
self.execution_queue.start()
|
|
865
|
+
# Check if daemon is running (for warning display later)
|
|
866
|
+
self.daemon_is_running = self._check_daemon_running()
|
|
849
867
|
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
logging.warning("Daemon is not running - scheduled actions will NOT execute until daemon is started")
|
|
868
|
+
# Initialise execution components (for manual "Run Now" from UI)
|
|
869
|
+
# Note: Scheduled execution is ONLY handled by the daemon process
|
|
870
|
+
self.action_scheduler.initialise()
|
|
871
|
+
self.execution_queue.start()
|
|
855
872
|
|
|
856
|
-
|
|
873
|
+
# UI never starts the scheduler - daemon handles all scheduled execution
|
|
874
|
+
if self.daemon_is_running:
|
|
875
|
+
logging.info("Daemon is running - scheduled actions will be executed by daemon")
|
|
876
|
+
else:
|
|
877
|
+
logging.warning("Daemon is not running - scheduled actions will NOT execute until daemon is started")
|
|
857
878
|
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
879
|
+
progress.update(task_scheduler, advance=100)
|
|
880
|
+
|
|
881
|
+
except ImportError as e:
|
|
882
|
+
logging.warning(f"Action scheduler not available (APScheduler not installed): {e}")
|
|
883
|
+
self.action_scheduler = None
|
|
884
|
+
self.execution_queue = None
|
|
885
|
+
self.action_executor = None
|
|
886
|
+
progress.update(task_scheduler, advance=100)
|
|
887
|
+
except Exception as e:
|
|
888
|
+
logging.error(f"Failed to initialise action scheduler: {e}")
|
|
889
|
+
self.action_scheduler = None
|
|
890
|
+
self.execution_queue = None
|
|
891
|
+
self.action_executor = None
|
|
892
|
+
progress.update(task_scheduler, advance=100)
|
|
870
893
|
|
|
871
894
|
# Display application info first (user identification)
|
|
872
895
|
self.cli.display_application_info(self.user_guid)
|
|
@@ -881,8 +904,8 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
881
904
|
if mcp_enabled and self.mcp_manager:
|
|
882
905
|
self.cli.display_mcp_status(self.mcp_manager)
|
|
883
906
|
|
|
884
|
-
# Display daemon status warning if daemon is not running
|
|
885
|
-
if hasattr(self, 'daemon_is_running') and not self.daemon_is_running:
|
|
907
|
+
# Display daemon status warning if daemon is not running (only when actions are enabled)
|
|
908
|
+
if self.actions_enabled and hasattr(self, 'daemon_is_running') and not self.daemon_is_running:
|
|
886
909
|
# Check if there are any scheduled actions
|
|
887
910
|
try:
|
|
888
911
|
actions = self.database.get_all_actions(include_disabled=False)
|
|
@@ -1638,7 +1661,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
1638
1661
|
enable_filesystem_tools = Confirm.ask("Enable embedded filesystem tools?", default=False)
|
|
1639
1662
|
|
|
1640
1663
|
# Default values
|
|
1641
|
-
filesystem_allowed_path =
|
|
1664
|
+
filesystem_allowed_path = _DEFAULT_RUNNING_DIR
|
|
1642
1665
|
filesystem_access_mode = "read_write"
|
|
1643
1666
|
|
|
1644
1667
|
if enable_filesystem_tools:
|
|
@@ -1648,7 +1671,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
1648
1671
|
|
|
1649
1672
|
filesystem_allowed_path = Prompt.ask(
|
|
1650
1673
|
"Allowed directory path (tools can only access files within this directory)",
|
|
1651
|
-
default=
|
|
1674
|
+
default=_DEFAULT_RUNNING_DIR
|
|
1652
1675
|
)
|
|
1653
1676
|
|
|
1654
1677
|
# Access mode
|
|
@@ -1661,7 +1684,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
1661
1684
|
cli.console.print(" [2] Read/Write - Full access (read + write files, create directories)")
|
|
1662
1685
|
cli.console.print()
|
|
1663
1686
|
access_mode_choice = Prompt.ask(
|
|
1664
|
-
|
|
1687
|
+
_PROMPT_ACCESS_MODE,
|
|
1665
1688
|
choices=["1", "2"],
|
|
1666
1689
|
default="2"
|
|
1667
1690
|
)
|
|
@@ -1674,7 +1697,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
1674
1697
|
enable_document_tools = Confirm.ask("Enable embedded document tools (MS Office & PDF)?", default=False)
|
|
1675
1698
|
|
|
1676
1699
|
# Default values
|
|
1677
|
-
document_allowed_path =
|
|
1700
|
+
document_allowed_path = _DEFAULT_RUNNING_DIR
|
|
1678
1701
|
document_access_mode = "read"
|
|
1679
1702
|
document_max_file_size = "50"
|
|
1680
1703
|
document_max_pdf_pages = "100"
|
|
@@ -1689,7 +1712,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
1689
1712
|
|
|
1690
1713
|
document_allowed_path = Prompt.ask(
|
|
1691
1714
|
"Allowed directory path for documents",
|
|
1692
|
-
default=
|
|
1715
|
+
default=_DEFAULT_RUNNING_DIR
|
|
1693
1716
|
)
|
|
1694
1717
|
|
|
1695
1718
|
# Access mode
|
|
@@ -1702,7 +1725,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
1702
1725
|
cli.console.print(" [2] Read/Write - Read and create documents")
|
|
1703
1726
|
cli.console.print()
|
|
1704
1727
|
doc_access_mode_choice = Prompt.ask(
|
|
1705
|
-
|
|
1728
|
+
_PROMPT_ACCESS_MODE,
|
|
1706
1729
|
choices=["1", "2"],
|
|
1707
1730
|
default="1"
|
|
1708
1731
|
)
|
|
@@ -1742,7 +1765,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
1742
1765
|
enable_archive_tools = Confirm.ask("Enable embedded archive tools (ZIP, TAR)?", default=False)
|
|
1743
1766
|
|
|
1744
1767
|
# Default values
|
|
1745
|
-
archive_allowed_path =
|
|
1768
|
+
archive_allowed_path = _DEFAULT_RUNNING_DIR
|
|
1746
1769
|
archive_access_mode = "read"
|
|
1747
1770
|
archive_max_file_size = "100"
|
|
1748
1771
|
archive_max_files_to_list = "1000"
|
|
@@ -1754,7 +1777,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
1754
1777
|
|
|
1755
1778
|
archive_allowed_path = Prompt.ask(
|
|
1756
1779
|
"Allowed directory path for archives",
|
|
1757
|
-
default=
|
|
1780
|
+
default=_DEFAULT_RUNNING_DIR
|
|
1758
1781
|
)
|
|
1759
1782
|
|
|
1760
1783
|
# Access mode
|
|
@@ -1767,7 +1790,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
1767
1790
|
cli.console.print(" [2] Read/Write - Read and extract archives to disk")
|
|
1768
1791
|
cli.console.print()
|
|
1769
1792
|
archive_access_mode_choice = Prompt.ask(
|
|
1770
|
-
|
|
1793
|
+
_PROMPT_ACCESS_MODE,
|
|
1771
1794
|
choices=["1", "2"],
|
|
1772
1795
|
default="1"
|
|
1773
1796
|
)
|
|
@@ -2211,14 +2234,14 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
2211
2234
|
if document_templates_path:
|
|
2212
2235
|
escaped_templates_path = document_templates_path.replace('\\', '/')
|
|
2213
2236
|
config_content = re.sub(
|
|
2214
|
-
r'(templates_path:\s+)(
|
|
2237
|
+
r'(templates_path:\s+)([^\s#]+)',
|
|
2215
2238
|
f'\\g<1>{escaped_templates_path}',
|
|
2216
2239
|
config_content
|
|
2217
2240
|
)
|
|
2218
2241
|
# Default author (if provided)
|
|
2219
2242
|
if document_default_author:
|
|
2220
2243
|
config_content = re.sub(
|
|
2221
|
-
r'(default_author:\s+)(
|
|
2244
|
+
r'(default_author:\s+)([^\s#]+)',
|
|
2222
2245
|
f'\\g<1>{document_default_author}',
|
|
2223
2246
|
config_content
|
|
2224
2247
|
)
|
|
@@ -2377,9 +2400,9 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
2377
2400
|
def regather_and_display_costs(self):
|
|
2378
2401
|
"""Re-gather AWS Bedrock cost information and display it."""
|
|
2379
2402
|
# Check if cost tracking is enabled (new path with legacy fallback)
|
|
2380
|
-
cost_tracking_enabled = self._get_nested_setting(
|
|
2403
|
+
cost_tracking_enabled = self._get_nested_setting(_SETTING_BEDROCK_COST_TRACKING, None)
|
|
2381
2404
|
if cost_tracking_enabled is None:
|
|
2382
|
-
cost_tracking_enabled = self.settings.get(
|
|
2405
|
+
cost_tracking_enabled = self.settings.get(_SETTING_COST_TRACKING, False)
|
|
2383
2406
|
if not cost_tracking_enabled:
|
|
2384
2407
|
self.cli.print_warning("Cost tracking is disabled in configuration")
|
|
2385
2408
|
return
|
|
@@ -2748,7 +2771,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
2748
2771
|
# Step 1: Select model (will be used for both creation and execution)
|
|
2749
2772
|
models = self.llm_manager.list_all_models()
|
|
2750
2773
|
if not models:
|
|
2751
|
-
self.cli.print_error(
|
|
2774
|
+
self.cli.print_error(_MSG_NO_MODELS)
|
|
2752
2775
|
return
|
|
2753
2776
|
|
|
2754
2777
|
self.cli.console.print("\n[bold cyan]Select Model[/bold cyan]")
|
|
@@ -2942,7 +2965,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
2942
2965
|
progress.update(task, advance=100)
|
|
2943
2966
|
|
|
2944
2967
|
if not models:
|
|
2945
|
-
self.cli.print_error(
|
|
2968
|
+
self.cli.print_error(_MSG_NO_MODELS)
|
|
2946
2969
|
return None
|
|
2947
2970
|
|
|
2948
2971
|
model_id = self.cli.display_models(models)
|
|
@@ -3223,7 +3246,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
3223
3246
|
# Check if conversation is predefined - if so, block file deletion
|
|
3224
3247
|
if self.database.is_conversation_predefined(self.conversation_manager.current_conversation_id):
|
|
3225
3248
|
self.cli.print_error("Cannot delete files from predefined conversations")
|
|
3226
|
-
self.cli.print_info(
|
|
3249
|
+
self.cli.print_info(_MSG_MANAGED_CONVERSATION)
|
|
3227
3250
|
self.cli.wait_for_enter()
|
|
3228
3251
|
continue
|
|
3229
3252
|
|
|
@@ -3247,7 +3270,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
3247
3270
|
file_ids_input = self.cli.get_input("File IDs to delete").strip()
|
|
3248
3271
|
|
|
3249
3272
|
if not file_ids_input:
|
|
3250
|
-
self.cli.print_info(
|
|
3273
|
+
self.cli.print_info(_MSG_DELETE_CANCELLED)
|
|
3251
3274
|
self.cli.wait_for_enter()
|
|
3252
3275
|
continue
|
|
3253
3276
|
|
|
@@ -3267,7 +3290,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
3267
3290
|
else:
|
|
3268
3291
|
self.cli.print_error("Failed to delete files")
|
|
3269
3292
|
else:
|
|
3270
|
-
self.cli.print_info(
|
|
3293
|
+
self.cli.print_info(_MSG_DELETE_CANCELLED)
|
|
3271
3294
|
else:
|
|
3272
3295
|
# Parse comma-separated IDs
|
|
3273
3296
|
try:
|
|
@@ -3297,7 +3320,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
3297
3320
|
if failed_ids:
|
|
3298
3321
|
self.cli.print_error(f"Failed to delete files with IDs: {', '.join(map(str, failed_ids))}")
|
|
3299
3322
|
else:
|
|
3300
|
-
self.cli.print_info(
|
|
3323
|
+
self.cli.print_info(_MSG_DELETE_CANCELLED)
|
|
3301
3324
|
|
|
3302
3325
|
except ValueError:
|
|
3303
3326
|
self.cli.print_error("Invalid file IDs. Please enter comma-separated numbers or 'all'")
|
|
@@ -3309,7 +3332,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
3309
3332
|
# Check if conversation is predefined - if so, block model changes
|
|
3310
3333
|
if self.database.is_conversation_predefined(self.conversation_manager.current_conversation_id):
|
|
3311
3334
|
self.cli.print_error("Cannot change model for predefined conversations")
|
|
3312
|
-
self.cli.print_info(
|
|
3335
|
+
self.cli.print_info(_MSG_MANAGED_CONVERSATION)
|
|
3313
3336
|
self.cli.wait_for_enter()
|
|
3314
3337
|
continue
|
|
3315
3338
|
|
|
@@ -3327,7 +3350,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
3327
3350
|
progress.update(task, advance=100)
|
|
3328
3351
|
|
|
3329
3352
|
if not models:
|
|
3330
|
-
self.cli.print_error(
|
|
3353
|
+
self.cli.print_error(_MSG_NO_MODELS)
|
|
3331
3354
|
self.cli.wait_for_enter()
|
|
3332
3355
|
continue
|
|
3333
3356
|
|
|
@@ -3374,7 +3397,7 @@ class AWSBedrockCLI(AbstractApp):
|
|
|
3374
3397
|
# Check if conversation is predefined - if so, block instruction changes
|
|
3375
3398
|
if self.database.is_conversation_predefined(self.conversation_manager.current_conversation_id):
|
|
3376
3399
|
self.cli.print_error("Cannot change instructions for predefined conversations")
|
|
3377
|
-
self.cli.print_info(
|
|
3400
|
+
self.cli.print_info(_MSG_MANAGED_CONVERSATION)
|
|
3378
3401
|
self.cli.wait_for_enter()
|
|
3379
3402
|
continue
|
|
3380
3403
|
|