ayechat-dev 0.36.9.20260204011001__tar.gz → 0.36.9.20260205232002__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.
- {ayechat_dev-0.36.9.20260204011001/src/ayechat_dev.egg-info → ayechat_dev-0.36.9.20260205232002}/PKG-INFO +1 -1
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/pyproject.toml +1 -1
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/controller/llm_invoker.py +65 -55
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/config.py +5 -0
- ayechat_dev-0.36.9.20260205232002/src/aye/plugins/databricks_model.py +312 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/plugins/local_model.py +0 -45
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002/src/ayechat_dev.egg-info}/PKG-INFO +1 -1
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/ayechat_dev.egg-info/SOURCES.txt +1 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.github/dependabot.yml +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.github/workflows/build-windows-installer.yml +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.github/workflows/message-releases-to-discord.yml +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.github/workflows/pylint.yml +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.github/workflows/python-publish-dev.yml +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.github/workflows/python-publish.yml +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.github/workflows/python-testing.yml +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.github/workflows/test-homebrew.yml +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.github/workflows/test-nix-github.yml +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.github/workflows/test-nix.yml +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.github/workflows/test-windows-installer.yml +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.github/workflows/update-homebrew.yml +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.gitignore +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.pylintrc +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/BUILD.md +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/DISCLAIMER +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/Formula/aye-chat.rb +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/LICENSE +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/README.md +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/assets/aye-chat.ico +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/aye-chat.spec +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/ayechat.nix +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/flake.lock +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/flake.nix +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/installer.iss +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/publish_pypi.sh +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/requirements.txt +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/run_tests.cmd +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/run_tests.sh +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/setup.cfg +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/.gitignore +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/__init__.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/__main__.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/__main_chat__.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/controller/__init__.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/controller/command_handlers.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/controller/commands.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/controller/llm_handler.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/controller/plugin_manager.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/controller/repl.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/controller/tutorial.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/controller/util.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/__init__.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/api.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/ast_chunker.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/auth.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/autodiff_config.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/download_plugins.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/file_processor.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/ignore_patterns.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/index_manager/__init__.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/index_manager/index_manager.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/index_manager/index_manager_executor.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/index_manager/index_manager_file_ops.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/index_manager/index_manager_state.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/index_manager/index_manager_utils.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/json_extractor.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/models.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/offline_llm_manager.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/onnx_manager.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/snapshot/__init__.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/snapshot/base.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/snapshot/file_backend.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/snapshot/git_ref_backend.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/source_collector.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/telemetry.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/vector_db.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/version_checker.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/write_validator.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/plugins/__init__.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/plugins/at_file_completer.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/plugins/auto_detect_mask.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/plugins/completer.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/plugins/offline_llm.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/plugins/plugin_base.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/plugins/shell_executor.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/plugins/slash_completer.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/presenter/__init__.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/presenter/cli_ui.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/presenter/diff_presenter.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/presenter/repl_ui.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/presenter/streaming_ui.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/presenter/ui_utils.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/ayechat_dev.egg-info/dependency_links.txt +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/ayechat_dev.egg-info/entry_points.txt +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/ayechat_dev.egg-info/requires.txt +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/ayechat_dev.egg-info/top_level.txt +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/.gitignore +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/config/unittest-env.sh +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/e2e/test_chat_workflow.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_api.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_ast_chunker.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_at_file_completer.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_auth.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_auth_uat_1.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_auto_detect_mask.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_chromadb_corruption_recovery.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_cli.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_command_handlers.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_commands.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_completer_plugin.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_config.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_diff_presenter.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_download_plugins.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_file_processor.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_git_ref_backend.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_index_manager.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_index_manager_executor.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_index_manager_more.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_index_manager_state.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_index_manager_utils.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_llm_handler.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_llm_invoker.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_local_model_plugin.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_offline_llm.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_offline_llm_manager.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_onnx_manager.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_plugin_base.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_plugin_manager.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_presenter.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_rag_context_retrieval.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_repl.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_service.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_shell_executor_plugin.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_slash_completer.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_snapshot.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_source_collector.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_streaming_ui.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_telemetry.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_tutorial.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_ui_utils.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_util.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_vector_db.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_version_checker.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_write_validator.py +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/ua/api_tests.md +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/ua/auth_tests.md +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/ua/demo_tests.md +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/ua/download_plugins_tests.md +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/ua/plugin_tests.md +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/ua/service_tests.md +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/ua/snapshot_tests.md +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/ua/source_collector_tests.md +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/ua/ui_tests.md +0 -0
- {ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/version_info.txt +0 -0
|
@@ -8,7 +8,7 @@ description = "Aye Chat: Terminal-first AI Code Generator"
|
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
requires-python = ">=3.10, <3.14"
|
|
10
10
|
dependencies = [ "typer>=0.20.0", "httpx>=0.28.1", "keyring>=25.7.0", "prompt-toolkit>=3.0.52", "pathspec>=0.12.1", "chromadb>=1.3.5", "rapidfuzz",]
|
|
11
|
-
version = "0.36.9.
|
|
11
|
+
version = "0.36.9.20260205232002"
|
|
12
12
|
[[project.authors]]
|
|
13
13
|
name = "Acrotron, Inc."
|
|
14
14
|
email = "info@acrotron.com"
|
|
@@ -13,12 +13,16 @@ from aye.model.source_collector import collect_sources
|
|
|
13
13
|
from aye.model.auth import get_user_config
|
|
14
14
|
from aye.model.offline_llm_manager import is_offline_model
|
|
15
15
|
from aye.controller.util import is_truncated_json
|
|
16
|
-
from aye.model.config import SYSTEM_PROMPT, MODELS, DEFAULT_MAX_OUTPUT_TOKENS, DEFAULT_CONTEXT_TARGET_KB
|
|
16
|
+
from aye.model.config import SYSTEM_PROMPT, MODELS, DEFAULT_MAX_OUTPUT_TOKENS, DEFAULT_CONTEXT_TARGET_KB, CONTEXT_HARD_LIMIT_KB
|
|
17
17
|
from aye.model import telemetry
|
|
18
18
|
|
|
19
19
|
import os
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
def _is_verbose():
|
|
23
|
+
return get_user_config("verbose", "off").lower() == "on"
|
|
24
|
+
|
|
25
|
+
|
|
22
26
|
def _is_debug():
|
|
23
27
|
return get_user_config("debug", "off").lower() == "on"
|
|
24
28
|
|
|
@@ -77,7 +81,7 @@ def _get_context_hard_limit(model_id: str) -> int:
|
|
|
77
81
|
model_config = _get_model_config(model_id)
|
|
78
82
|
if model_config and "max_prompt_kb" in model_config:
|
|
79
83
|
return model_config["max_prompt_kb"] * 1024
|
|
80
|
-
return
|
|
84
|
+
return CONTEXT_HARD_LIMIT_KB * 1024
|
|
81
85
|
|
|
82
86
|
|
|
83
87
|
def _filter_ground_truth(files: Dict[str, str], conf: Any, verbose: bool) -> Dict[str, str]:
|
|
@@ -134,6 +138,8 @@ def _get_rag_context_files(prompt: str, conf: Any, verbose: bool) -> Dict[str, s
|
|
|
134
138
|
|
|
135
139
|
context_target_size = _get_context_target_size(conf.selected_model)
|
|
136
140
|
context_hard_limit = _get_context_hard_limit(conf.selected_model)
|
|
141
|
+
#context_target_size = DEFAULT_CONTEXT_TARGET_KB #_get_context_target_size(conf.selected_model)
|
|
142
|
+
#context_hard_limit = CONTEXT_HARD_LIMIT_KB # _get_context_hard_limit(conf.selected_model)
|
|
137
143
|
|
|
138
144
|
if _is_debug():
|
|
139
145
|
rprint(f"[yellow]Context target: {context_target_size / 1024:.1f}KB, hard limit: {context_hard_limit / 1024:.1f}KB[/]")
|
|
@@ -298,50 +304,54 @@ def invoke_llm(
|
|
|
298
304
|
model_config = _get_model_config(conf.selected_model)
|
|
299
305
|
max_output_tokens = model_config.get("max_output_tokens", DEFAULT_MAX_OUTPUT_TOKENS) if model_config else DEFAULT_MAX_OUTPUT_TOKENS
|
|
300
306
|
|
|
301
|
-
#
|
|
302
|
-
local_response = plugin_manager.handle_command("local_model_invoke", {
|
|
303
|
-
"prompt": prompt,
|
|
304
|
-
"model_id": conf.selected_model,
|
|
305
|
-
"source_files": source_files,
|
|
306
|
-
"chat_id": chat_id,
|
|
307
|
-
"root": conf.root,
|
|
308
|
-
"system_prompt": system_prompt,
|
|
309
|
-
"max_output_tokens": max_output_tokens
|
|
310
|
-
})
|
|
311
|
-
|
|
312
|
-
if local_response is not None:
|
|
313
|
-
return LLMResponse(
|
|
314
|
-
summary=local_response.get("summary", ""),
|
|
315
|
-
updated_files=local_response.get("updated_files", []),
|
|
316
|
-
chat_id=None,
|
|
317
|
-
source=LLMSource.LOCAL
|
|
318
|
-
)
|
|
319
|
-
|
|
320
|
-
# 2. API call with spinner + streaming display
|
|
321
|
-
if _is_debug():
|
|
322
|
-
print(f"[DEBUG] Processing chat message with chat_id={chat_id or -1}, model={conf.selected_model}")
|
|
323
|
-
|
|
324
|
-
telemetry_payload = telemetry.build_payload(top_n=20) if telemetry.is_enabled() else None
|
|
325
|
-
|
|
326
|
-
# Create spinner - will be stopped when streaming starts
|
|
307
|
+
# Create spinner - will be shown for ALL model types (local, databricks, API)
|
|
327
308
|
spinner = StoppableSpinner(
|
|
328
309
|
console,
|
|
329
310
|
messages=DEFAULT_THINKING_MESSAGES,
|
|
330
311
|
interval=15.0
|
|
331
312
|
)
|
|
332
313
|
|
|
314
|
+
# For API calls, we also have streaming display
|
|
315
|
+
streaming_display: Optional[StreamingResponseDisplay] = None
|
|
316
|
+
|
|
333
317
|
def stop_spinner():
|
|
334
|
-
"""Callback to stop spinner when first content arrives."""
|
|
318
|
+
"""Callback to stop spinner when first content arrives (for streaming API)."""
|
|
335
319
|
spinner.stop()
|
|
336
|
-
|
|
337
|
-
# Create streaming display with callback to stop spinner on first content
|
|
338
|
-
streaming_display = StreamingResponseDisplay(on_first_content=stop_spinner)
|
|
339
|
-
stream_callback = create_streaming_callback(streaming_display)
|
|
340
320
|
|
|
341
321
|
try:
|
|
342
|
-
# Start the spinner before
|
|
322
|
+
# Start the spinner before ANY LLM call (local or API)
|
|
343
323
|
spinner.start()
|
|
344
324
|
|
|
325
|
+
# 1. Try local/offline model plugins first
|
|
326
|
+
local_response = plugin_manager.handle_command("local_model_invoke", {
|
|
327
|
+
"prompt": prompt,
|
|
328
|
+
"model_id": conf.selected_model,
|
|
329
|
+
"source_files": source_files,
|
|
330
|
+
"chat_id": chat_id,
|
|
331
|
+
"root": conf.root,
|
|
332
|
+
"system_prompt": system_prompt,
|
|
333
|
+
"max_output_tokens": max_output_tokens
|
|
334
|
+
})
|
|
335
|
+
|
|
336
|
+
if local_response is not None:
|
|
337
|
+
# Local model handled the request - spinner will be stopped in finally block
|
|
338
|
+
return LLMResponse(
|
|
339
|
+
summary=local_response.get("summary", ""),
|
|
340
|
+
updated_files=local_response.get("updated_files", []),
|
|
341
|
+
chat_id=None,
|
|
342
|
+
source=LLMSource.LOCAL
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
# 2. API call with streaming display
|
|
346
|
+
if _is_debug():
|
|
347
|
+
print(f"[DEBUG] Processing chat message with chat_id={chat_id or -1}, model={conf.selected_model}")
|
|
348
|
+
|
|
349
|
+
telemetry_payload = telemetry.build_payload(top_n=20) if telemetry.is_enabled() else None
|
|
350
|
+
|
|
351
|
+
# Create streaming display with callback to stop spinner on first content
|
|
352
|
+
streaming_display = StreamingResponseDisplay(on_first_content=stop_spinner)
|
|
353
|
+
stream_callback = create_streaming_callback(streaming_display)
|
|
354
|
+
|
|
345
355
|
api_resp = cli_invoke(
|
|
346
356
|
message=prompt,
|
|
347
357
|
chat_id=chat_id or -1,
|
|
@@ -352,29 +362,29 @@ def invoke_llm(
|
|
|
352
362
|
telemetry=telemetry_payload,
|
|
353
363
|
on_stream_update=stream_callback
|
|
354
364
|
)
|
|
355
|
-
finally:
|
|
356
|
-
# Ensure spinner is stopped (in case no streaming content was received)
|
|
357
|
-
spinner.stop()
|
|
358
|
-
|
|
359
|
-
# Always stop the streaming display when done
|
|
360
|
-
if streaming_display.is_active():
|
|
361
|
-
streaming_display.stop()
|
|
362
365
|
|
|
363
|
-
|
|
364
|
-
|
|
366
|
+
if telemetry_payload is not None:
|
|
367
|
+
telemetry.reset()
|
|
365
368
|
|
|
366
|
-
|
|
367
|
-
|
|
369
|
+
if _is_debug():
|
|
370
|
+
print(f"[DEBUG] Chat message processed, response keys: {api_resp.keys() if api_resp else 'None'}")
|
|
368
371
|
|
|
369
|
-
|
|
370
|
-
|
|
372
|
+
# Check if we already displayed the response via streaming
|
|
373
|
+
streamed_summary = bool(api_resp.get("_streamed_summary")) if isinstance(api_resp, dict) else False
|
|
371
374
|
|
|
372
|
-
|
|
373
|
-
|
|
375
|
+
# 3. Parse API response
|
|
376
|
+
assistant_resp, new_chat_id = _parse_api_response(api_resp)
|
|
374
377
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
378
|
+
return LLMResponse(
|
|
379
|
+
summary="" if streamed_summary else assistant_resp.get("answer_summary", ""),
|
|
380
|
+
updated_files=assistant_resp.get("source_files", []),
|
|
381
|
+
chat_id=new_chat_id,
|
|
382
|
+
source=LLMSource.API
|
|
383
|
+
)
|
|
384
|
+
finally:
|
|
385
|
+
# Ensure spinner is stopped for ALL code paths (local model, API, or error)
|
|
386
|
+
spinner.stop()
|
|
387
|
+
|
|
388
|
+
# Stop the streaming display if it was created and is active
|
|
389
|
+
if streaming_display is not None and streaming_display.is_active():
|
|
390
|
+
streaming_display.stop()
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/config.py
RENAMED
|
@@ -17,12 +17,17 @@ SMALL_PROJECT_FILE_LIMIT = 200
|
|
|
17
17
|
# Projects smaller than this will skip RAG and include all files directly.
|
|
18
18
|
# Set to match default max_prompt_kb (170KB) so all files can fit in context.
|
|
19
19
|
SMALL_PROJECT_TOTAL_SIZE_LIMIT = 170 * 1024 # 170KB
|
|
20
|
+
#SMALL_PROJECT_TOTAL_SIZE_LIMIT = 100 * 1024 # 170KB
|
|
20
21
|
|
|
21
22
|
# Default maximum output tokens for LLM responses
|
|
22
23
|
DEFAULT_MAX_OUTPUT_TOKENS = 32000
|
|
24
|
+
#DEFAULT_MAX_OUTPUT_TOKENS = 16000
|
|
23
25
|
|
|
24
26
|
# Default context target size in KB (used when model doesn't specify one)
|
|
25
27
|
DEFAULT_CONTEXT_TARGET_KB = 150
|
|
28
|
+
#DEFAULT_CONTEXT_TARGET_KB = 20
|
|
29
|
+
|
|
30
|
+
CONTEXT_HARD_LIMIT_KB = 170
|
|
26
31
|
|
|
27
32
|
# Shared system prompt for all LLM interactions
|
|
28
33
|
SYSTEM_PROMPT = (
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import json
|
|
3
|
+
from typing import Dict, Any, Optional
|
|
4
|
+
import httpx
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
import traceback
|
|
7
|
+
|
|
8
|
+
from rich import print as rprint
|
|
9
|
+
|
|
10
|
+
from .plugin_base import Plugin
|
|
11
|
+
from aye.model.config import SYSTEM_PROMPT, MODELS, DEFAULT_MAX_OUTPUT_TOKENS
|
|
12
|
+
from aye.model.auth import get_user_config
|
|
13
|
+
from aye.controller.util import is_truncated_json
|
|
14
|
+
|
|
15
|
+
LLM_TIMEOUT = 600.0
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Message shown when LLM response is truncated due to output token limits
|
|
19
|
+
TRUNCATED_RESPONSE_MESSAGE = (
|
|
20
|
+
"It looks like my response was cut off because it exceeded the output limit. "
|
|
21
|
+
"This usually happens when you ask me to generate or modify many files at once.\n\n"
|
|
22
|
+
"**To fix this, please try:**\n"
|
|
23
|
+
"1. Break your request into smaller parts (e.g., one file at a time)\n"
|
|
24
|
+
"2. Use the `with` command to focus on specific files: `with file1.py, file2.py: your request`\n"
|
|
25
|
+
"3. Ask me to work on fewer files or smaller changes in each request\n\n"
|
|
26
|
+
"For example, instead of 'update all files to add logging', try:\n"
|
|
27
|
+
" `with src/main.py: add logging to this file`"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _get_model_config(model_id: str) -> Optional[Dict[str, Any]]:
|
|
32
|
+
"""Get configuration for a specific model."""
|
|
33
|
+
for model in MODELS:
|
|
34
|
+
if model["id"] == model_id:
|
|
35
|
+
return model
|
|
36
|
+
return None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _extract_json_object(raw_response: str, prefer_last: bool = True, require_keys=None):
|
|
40
|
+
"""
|
|
41
|
+
Best-effort extraction of a JSON object (dict) from a raw LLM response.
|
|
42
|
+
|
|
43
|
+
Handles common failure modes where the model returns:
|
|
44
|
+
- extra commentary before/after JSON
|
|
45
|
+
- multiple JSON objects (e.g., an invalid attempt + a corrected attempt)
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
raw_response: raw LLM response string
|
|
49
|
+
prefer_last: when multiple JSON objects exist, return the last parsed object
|
|
50
|
+
require_keys: optional iterable of keys; if provided, only consider objects
|
|
51
|
+
that contain all of these keys
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
dict or None
|
|
55
|
+
"""
|
|
56
|
+
# 1) Direct JSON parse
|
|
57
|
+
try:
|
|
58
|
+
obj = json.loads(raw_response)
|
|
59
|
+
if isinstance(obj, dict):
|
|
60
|
+
if require_keys and not all(k in obj for k in require_keys):
|
|
61
|
+
return None
|
|
62
|
+
return obj
|
|
63
|
+
except Exception:
|
|
64
|
+
pass
|
|
65
|
+
|
|
66
|
+
text = str(raw_response)
|
|
67
|
+
|
|
68
|
+
# 2) Scan for balanced JSON object candidates (string/escape-aware)
|
|
69
|
+
candidates = []
|
|
70
|
+
depth = 0
|
|
71
|
+
start = None
|
|
72
|
+
in_str = False
|
|
73
|
+
escape = False
|
|
74
|
+
|
|
75
|
+
for i, ch in enumerate(text):
|
|
76
|
+
if in_str:
|
|
77
|
+
if escape:
|
|
78
|
+
escape = False
|
|
79
|
+
elif ch == '\\':
|
|
80
|
+
escape = True
|
|
81
|
+
elif ch == '"':
|
|
82
|
+
in_str = False
|
|
83
|
+
continue
|
|
84
|
+
|
|
85
|
+
# not in string
|
|
86
|
+
if ch == '"':
|
|
87
|
+
in_str = True
|
|
88
|
+
continue
|
|
89
|
+
|
|
90
|
+
if ch == '{':
|
|
91
|
+
if depth == 0:
|
|
92
|
+
start = i
|
|
93
|
+
depth += 1
|
|
94
|
+
elif ch == '}' and depth > 0:
|
|
95
|
+
depth -= 1
|
|
96
|
+
if depth == 0 and start is not None:
|
|
97
|
+
candidates.append(text[start : i + 1])
|
|
98
|
+
start = None
|
|
99
|
+
|
|
100
|
+
parsed = []
|
|
101
|
+
for cand in candidates:
|
|
102
|
+
try:
|
|
103
|
+
obj = json.loads(cand)
|
|
104
|
+
if not isinstance(obj, dict):
|
|
105
|
+
continue
|
|
106
|
+
if require_keys and not all(k in obj for k in require_keys):
|
|
107
|
+
continue
|
|
108
|
+
parsed.append(obj)
|
|
109
|
+
except Exception:
|
|
110
|
+
continue
|
|
111
|
+
|
|
112
|
+
if not parsed:
|
|
113
|
+
return None
|
|
114
|
+
|
|
115
|
+
return parsed[-1] if prefer_last else parsed[0]
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class DatabricksModelPlugin(Plugin):
|
|
119
|
+
name = "databricks_model"
|
|
120
|
+
version = "1.0.0"
|
|
121
|
+
premium = "free"
|
|
122
|
+
|
|
123
|
+
def __init__(self):
|
|
124
|
+
super().__init__()
|
|
125
|
+
self.chat_history: Dict[str, list] = {}
|
|
126
|
+
self.history_file: Optional[Path] = None
|
|
127
|
+
|
|
128
|
+
def init(self, cfg: Dict[str, Any]) -> None:
|
|
129
|
+
"""Initialize the local model plugin."""
|
|
130
|
+
super().init(cfg)
|
|
131
|
+
if self.debug:
|
|
132
|
+
rprint(f"[bold yellow]Initializing {self.name} v{self.version}[/]")
|
|
133
|
+
|
|
134
|
+
def _load_history(self) -> None:
|
|
135
|
+
"""Load chat history from disk."""
|
|
136
|
+
if not self.history_file:
|
|
137
|
+
if self.verbose:
|
|
138
|
+
rprint("[yellow]History file path not set for local model. Skipping load.[/]")
|
|
139
|
+
self.chat_history = {}
|
|
140
|
+
return
|
|
141
|
+
|
|
142
|
+
if self.history_file.exists():
|
|
143
|
+
try:
|
|
144
|
+
data = json.loads(self.history_file.read_text(encoding="utf-8"))
|
|
145
|
+
self.chat_history = data.get("conversations", {})
|
|
146
|
+
except Exception as e:
|
|
147
|
+
if self.verbose:
|
|
148
|
+
rprint(f"[yellow]Could not load chat history: {e}[/]")
|
|
149
|
+
self.chat_history = {}
|
|
150
|
+
else:
|
|
151
|
+
self.chat_history = {}
|
|
152
|
+
|
|
153
|
+
def _save_history(self) -> None:
|
|
154
|
+
"""Save chat history to disk."""
|
|
155
|
+
if not self.history_file:
|
|
156
|
+
if self.verbose:
|
|
157
|
+
rprint("[yellow]History file path not set for local model. Skipping save.[/]")
|
|
158
|
+
return
|
|
159
|
+
|
|
160
|
+
try:
|
|
161
|
+
self.history_file.parent.mkdir(parents=True, exist_ok=True)
|
|
162
|
+
data = {"conversations": self.chat_history}
|
|
163
|
+
self.history_file.write_text(json.dumps(data, indent=2), encoding="utf-8")
|
|
164
|
+
except Exception as e:
|
|
165
|
+
if self.verbose:
|
|
166
|
+
rprint(f"[yellow]Could not save chat history: {e}[/]")
|
|
167
|
+
|
|
168
|
+
def _get_conversation_id(self, chat_id: Optional[int] = None) -> str:
|
|
169
|
+
"""Get conversation ID for history tracking."""
|
|
170
|
+
return str(chat_id) if chat_id and chat_id > 0 else "default"
|
|
171
|
+
|
|
172
|
+
def _build_user_message(self, prompt: str, source_files: Dict[str, str]) -> str:
|
|
173
|
+
"""Build the user message with optional source files appended."""
|
|
174
|
+
user_message = prompt
|
|
175
|
+
if source_files:
|
|
176
|
+
user_message += "\n\n--- Source files are below. ---\n"
|
|
177
|
+
for file_name, content in source_files.items():
|
|
178
|
+
user_message += f"\n** {file_name} **\n```\n{content}\n```\n"
|
|
179
|
+
return user_message
|
|
180
|
+
|
|
181
|
+
def _parse_llm_response(self, generated_text: str) -> Dict[str, Any]:
|
|
182
|
+
"""Parse LLM response text and convert to expected format."""
|
|
183
|
+
try:
|
|
184
|
+
llm_response = json.loads(generated_text)
|
|
185
|
+
except json.JSONDecodeError:
|
|
186
|
+
# Check if this looks like a truncated response
|
|
187
|
+
#if is_truncated_json(generated_text):
|
|
188
|
+
# return {
|
|
189
|
+
# "summary": TRUNCATED_RESPONSE_MESSAGE,
|
|
190
|
+
# "updated_files": []
|
|
191
|
+
# }
|
|
192
|
+
|
|
193
|
+
# Not truncated, just malformed - return as plain text
|
|
194
|
+
llm_response = {
|
|
195
|
+
"answer_summary": generated_text,
|
|
196
|
+
"source_files": []
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return {
|
|
200
|
+
"summary": llm_response.get("answer_summary", ""),
|
|
201
|
+
"updated_files": [
|
|
202
|
+
{
|
|
203
|
+
"file_name": f.get("file_name"),
|
|
204
|
+
"file_content": f.get("file_content")
|
|
205
|
+
}
|
|
206
|
+
for f in llm_response.get("source_files", [])
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
def _create_error_response(self, error_msg: str) -> Dict[str, Any]:
|
|
211
|
+
"""Create a standardized error response."""
|
|
212
|
+
if self.verbose:
|
|
213
|
+
rprint(f"[red]{error_msg}[/]")
|
|
214
|
+
return {
|
|
215
|
+
"summary": error_msg,
|
|
216
|
+
"updated_files": []
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
def _handle_databricks(self, prompt: str, source_files: Dict[str, str], chat_id: Optional[int] = None, system_prompt: Optional[str] = None, max_output_tokens: int = DEFAULT_MAX_OUTPUT_TOKENS) -> Optional[Dict[str, Any]]:
|
|
220
|
+
api_url = os.environ.get("AYE_DBX_API_URL")
|
|
221
|
+
api_key = os.environ.get("AYE_DBX_API_KEY")
|
|
222
|
+
model_name = os.environ.get("AYE_DBX_MODEL", "gpt-3.5-turbo")
|
|
223
|
+
|
|
224
|
+
if not api_url or not api_key:
|
|
225
|
+
return None
|
|
226
|
+
|
|
227
|
+
conv_id = self._get_conversation_id(chat_id)
|
|
228
|
+
if conv_id not in self.chat_history:
|
|
229
|
+
self.chat_history[conv_id] = []
|
|
230
|
+
|
|
231
|
+
user_message = self._build_user_message(prompt, source_files)
|
|
232
|
+
effective_system_prompt = system_prompt if system_prompt else SYSTEM_PROMPT
|
|
233
|
+
|
|
234
|
+
messages_json = [{"role": "system", "content": effective_system_prompt}] + self.chat_history[conv_id] + [{"role": "user", "content": user_message}]
|
|
235
|
+
messages = messages_json # json.dumps(messages_json)
|
|
236
|
+
if self.debug:
|
|
237
|
+
print(">>>>>>>>>>>>>>>>")
|
|
238
|
+
print(self.chat_history[conv_id])
|
|
239
|
+
print(">>>>>>>>>>>>>>>>")
|
|
240
|
+
|
|
241
|
+
headers = {"Content-Type": "application/json", "Authorization": f"Bearer {api_key}"}
|
|
242
|
+
#payload = {"model": model_name, "messages": messages, "temperature": 0.7, "max_tokens": max_output_tokens, "response_format": {"type": "json_object"}}
|
|
243
|
+
payload = {"model": model_name, "messages": messages, "temperature": 0.7, "max_tokens": max_output_tokens}
|
|
244
|
+
|
|
245
|
+
try:
|
|
246
|
+
with httpx.Client(timeout=LLM_TIMEOUT) as client:
|
|
247
|
+
response = client.post(api_url, json=payload, headers=headers)
|
|
248
|
+
if self.verbose and response.status_code != 200:
|
|
249
|
+
print(f"Status code: {response.status_code}")
|
|
250
|
+
print("-----------------")
|
|
251
|
+
print(response.text)
|
|
252
|
+
print("-----------------")
|
|
253
|
+
response.raise_for_status()
|
|
254
|
+
result = response.json()
|
|
255
|
+
if result.get("choices") and result["choices"][0].get("message"):
|
|
256
|
+
raw_response = result["choices"][0]["message"]["content"]
|
|
257
|
+
generated_json = _extract_json_object(raw_response)
|
|
258
|
+
generated_text = json.dumps(generated_json)
|
|
259
|
+
if self.debug:
|
|
260
|
+
print("-----------------")
|
|
261
|
+
print(response.text)
|
|
262
|
+
print("-----------------")
|
|
263
|
+
print(generated_text)
|
|
264
|
+
print("-----------------")
|
|
265
|
+
#generated_text = result["choices"][0]["message"]["content"][1]["text"]
|
|
266
|
+
self.chat_history[conv_id].append({"role": "user", "content": user_message})
|
|
267
|
+
self.chat_history[conv_id].append({"role": "assistant", "content": generated_text})
|
|
268
|
+
self._save_history()
|
|
269
|
+
#return json.dumps(generated_text)
|
|
270
|
+
return self._parse_llm_response(generated_text)
|
|
271
|
+
return self._create_error_response("Failed to get a valid response from the Databricks API")
|
|
272
|
+
except httpx.HTTPStatusError as e:
|
|
273
|
+
traceback.print_exc()
|
|
274
|
+
error_msg = f"DBX API error: {e.response.status_code}"
|
|
275
|
+
try:
|
|
276
|
+
error_detail = e.response.json()
|
|
277
|
+
if "error" in error_detail:
|
|
278
|
+
error_msg += f" - {error_detail['error'].get('message', str(error_detail['error']))}"
|
|
279
|
+
except: error_msg += f" - {e.response.text[:200]}"
|
|
280
|
+
return self._create_error_response(error_msg)
|
|
281
|
+
except Exception as e:
|
|
282
|
+
traceback.print_exc()
|
|
283
|
+
return self._create_error_response(f"Error calling Databricks API: {str(e)}")
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def on_command(self, command_name: str, params: Dict[str, Any]) -> Optional[Dict[str, Any]]:
|
|
287
|
+
if command_name == "new_chat":
|
|
288
|
+
root = params.get("root")
|
|
289
|
+
history_file = Path(root) / ".aye" / "chat_history.json" if root else Path.cwd() / ".aye" / "chat_history.json"
|
|
290
|
+
history_file.unlink(missing_ok=True)
|
|
291
|
+
self.chat_history = {}
|
|
292
|
+
if self.verbose: rprint("[yellow]Local model chat history cleared.[/]")
|
|
293
|
+
return {"status": "local_history_cleared"}
|
|
294
|
+
|
|
295
|
+
if command_name == "local_model_invoke":
|
|
296
|
+
prompt = params.get("prompt", "").strip()
|
|
297
|
+
model_id = params.get("model_id", "")
|
|
298
|
+
source_files = params.get("source_files", {})
|
|
299
|
+
chat_id = params.get("chat_id")
|
|
300
|
+
root = params.get("root")
|
|
301
|
+
system_prompt = params.get("system_prompt")
|
|
302
|
+
max_output_tokens = params.get("max_output_tokens", DEFAULT_MAX_OUTPUT_TOKENS)
|
|
303
|
+
|
|
304
|
+
self.history_file = Path(root) / ".aye" / "chat_history.json" if root else Path.cwd() / ".aye" / "chat_history.json"
|
|
305
|
+
self._load_history()
|
|
306
|
+
|
|
307
|
+
result = self._handle_databricks(prompt, source_files, chat_id, system_prompt, max_output_tokens)
|
|
308
|
+
if result is not None: return result
|
|
309
|
+
|
|
310
|
+
return None
|
|
311
|
+
|
|
312
|
+
return None
|
|
@@ -136,48 +136,6 @@ class LocalModelPlugin(Plugin):
|
|
|
136
136
|
"updated_files": []
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
def _handle_databricks(self, prompt: str, source_files: Dict[str, str], chat_id: Optional[int] = None, system_prompt: Optional[str] = None, max_output_tokens: int = DEFAULT_MAX_OUTPUT_TOKENS) -> Optional[Dict[str, Any]]:
|
|
140
|
-
api_url = os.environ.get("AYE_DBX_API_URL")
|
|
141
|
-
api_key = os.environ.get("AYE_DBX_API_KEY")
|
|
142
|
-
model_name = os.environ.get("AYE_DBX_MODEL", "gpt-3.5-turbo")
|
|
143
|
-
|
|
144
|
-
if not api_url or not api_key:
|
|
145
|
-
return None
|
|
146
|
-
|
|
147
|
-
conv_id = self._get_conversation_id(chat_id)
|
|
148
|
-
if conv_id not in self.chat_history:
|
|
149
|
-
self.chat_history[conv_id] = []
|
|
150
|
-
|
|
151
|
-
user_message = self._build_user_message(prompt, source_files)
|
|
152
|
-
effective_system_prompt = system_prompt if system_prompt else SYSTEM_PROMPT
|
|
153
|
-
|
|
154
|
-
messages = [{"role": "system", "content": effective_system_prompt}] + self.chat_history[conv_id] + [{"role": "user", "content": user_message}]
|
|
155
|
-
|
|
156
|
-
headers = {"Content-Type": "application/json", "Authorization": f"Bearer {api_key}"}
|
|
157
|
-
payload = {"model": model_name, "messages": messages, "temperature": 0.7, "max_tokens": max_output_tokens, "response_format": {"type": "json_object"}}
|
|
158
|
-
|
|
159
|
-
try:
|
|
160
|
-
with httpx.Client(timeout=LLM_TIMEOUT) as client:
|
|
161
|
-
response = client.post(api_url, json=payload, headers=headers)
|
|
162
|
-
response.raise_for_status()
|
|
163
|
-
result = response.json()
|
|
164
|
-
if result.get("choices") and result["choices"][0].get("message"):
|
|
165
|
-
generated_text = result["choices"][0]["message"]["content"][0]["text"]
|
|
166
|
-
self.chat_history[conv_id].append({"role": "user", "content": user_message})
|
|
167
|
-
self.chat_history[conv_id].append({"role": "assistant", "content": generated_text})
|
|
168
|
-
self._save_history()
|
|
169
|
-
return self._parse_llm_response(generated_text)
|
|
170
|
-
return self._create_error_response("Failed to get a valid response from the Databricks API")
|
|
171
|
-
except httpx.HTTPStatusError as e:
|
|
172
|
-
error_msg = f"DBX API error: {e.response.status_code}"
|
|
173
|
-
try:
|
|
174
|
-
error_detail = e.response.json()
|
|
175
|
-
if "error" in error_detail:
|
|
176
|
-
error_msg += f" - {error_detail['error'].get('message', str(error_detail['error']))}"
|
|
177
|
-
except: error_msg += f" - {e.response.text[:200]}"
|
|
178
|
-
return self._create_error_response(error_msg)
|
|
179
|
-
except Exception as e:
|
|
180
|
-
return self._create_error_response(f"Error calling Databricks API: {str(e)}")
|
|
181
139
|
|
|
182
140
|
def _handle_openai_compatible(self, prompt: str, source_files: Dict[str, str], chat_id: Optional[int] = None, system_prompt: Optional[str] = None, max_output_tokens: int = DEFAULT_MAX_OUTPUT_TOKENS) -> Optional[Dict[str, Any]]:
|
|
183
141
|
"""Handle OpenAI-compatible API endpoints.
|
|
@@ -288,9 +246,6 @@ class LocalModelPlugin(Plugin):
|
|
|
288
246
|
result = self._handle_openai_compatible(prompt, source_files, chat_id, system_prompt, max_output_tokens)
|
|
289
247
|
if result is not None: return result
|
|
290
248
|
|
|
291
|
-
result = self._handle_databricks(prompt, source_files, chat_id, system_prompt, max_output_tokens)
|
|
292
|
-
if result is not None: return result
|
|
293
|
-
|
|
294
249
|
if model_id == "google/gemini-2.5-pro":
|
|
295
250
|
return self._handle_gemini_pro_25(prompt, source_files, chat_id, system_prompt, max_output_tokens)
|
|
296
251
|
|
|
@@ -77,6 +77,7 @@ src/aye/plugins/__init__.py
|
|
|
77
77
|
src/aye/plugins/at_file_completer.py
|
|
78
78
|
src/aye/plugins/auto_detect_mask.py
|
|
79
79
|
src/aye/plugins/completer.py
|
|
80
|
+
src/aye/plugins/databricks_model.py
|
|
80
81
|
src/aye/plugins/local_model.py
|
|
81
82
|
src/aye/plugins/offline_llm.py
|
|
82
83
|
src/aye/plugins/plugin_base.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.github/dependabot.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/.github/workflows/pylint.yml
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
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/__main_chat__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/controller/repl.py
RENAMED
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/controller/util.py
RENAMED
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/__init__.py
RENAMED
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/api.py
RENAMED
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/ast_chunker.py
RENAMED
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/auth.py
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
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/models.py
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
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/telemetry.py
RENAMED
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/model/vector_db.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/plugins/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/plugins/completer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/presenter/cli_ui.py
RENAMED
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/src/aye/presenter/repl_ui.py
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
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/config/unittest-env.sh
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_ast_chunker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_auth_uat_1.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_commands.py
RENAMED
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_config.py
RENAMED
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_diff_presenter.py
RENAMED
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_file_processor.py
RENAMED
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_index_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_llm_handler.py
RENAMED
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_llm_invoker.py
RENAMED
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_offline_llm.py
RENAMED
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_onnx_manager.py
RENAMED
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_plugin_base.py
RENAMED
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_plugin_manager.py
RENAMED
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_presenter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_service.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_snapshot.py
RENAMED
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_streaming_ui.py
RENAMED
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_telemetry.py
RENAMED
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_tutorial.py
RENAMED
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_ui_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/test_vector_db.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/ua/api_tests.md
RENAMED
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/ua/auth_tests.md
RENAMED
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/ua/demo_tests.md
RENAMED
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/ua/plugin_tests.md
RENAMED
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/ua/service_tests.md
RENAMED
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/ua/snapshot_tests.md
RENAMED
|
File without changes
|
|
File without changes
|
{ayechat_dev-0.36.9.20260204011001 → ayechat_dev-0.36.9.20260205232002}/tests/ua/ui_tests.md
RENAMED
|
File without changes
|
|
File without changes
|