MaiBot 1.3.8__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.
- maibot-1.3.8.dist-info/METADATA +245 -0
- maibot-1.3.8.dist-info/RECORD +716 -0
- maibot-1.3.8.dist-info/WHEEL +5 -0
- maibot-1.3.8.dist-info/entry_points.txt +2 -0
- maibot-1.3.8.dist-info/licenses/LICENSE +674 -0
- maibot-1.3.8.dist-info/top_level.txt +1 -0
- src/A_memorix/LICENSE +661 -0
- src/A_memorix/LICENSE-MAIBOT-GPL.md +22 -0
- src/A_memorix/__init__.py +5 -0
- src/A_memorix/config_schema.json +1640 -0
- src/A_memorix/core/__init__.py +83 -0
- src/A_memorix/core/embedding/__init__.py +17 -0
- src/A_memorix/core/embedding/api_adapter.py +650 -0
- src/A_memorix/core/embedding/manager.py +506 -0
- src/A_memorix/core/embedding/presets.py +68 -0
- src/A_memorix/core/image/__init__.py +6 -0
- src/A_memorix/core/image/asset_store.py +141 -0
- src/A_memorix/core/image/component_paths.py +36 -0
- src/A_memorix/core/image/embedder.py +129 -0
- src/A_memorix/core/image/fingerprints.py +36 -0
- src/A_memorix/core/image/runtime.py +900 -0
- src/A_memorix/core/retrieval/__init__.py +66 -0
- src/A_memorix/core/retrieval/dual_path.py +3272 -0
- src/A_memorix/core/retrieval/graph_relation_recall.py +285 -0
- src/A_memorix/core/retrieval/pagerank.py +471 -0
- src/A_memorix/core/retrieval/posterior_graph.py +787 -0
- src/A_memorix/core/retrieval/score_calibration.py +180 -0
- src/A_memorix/core/retrieval/sparse_bm25.py +717 -0
- src/A_memorix/core/retrieval/threshold.py +404 -0
- src/A_memorix/core/runtime/__init__.py +26 -0
- src/A_memorix/core/runtime/admin_contracts.py +293 -0
- src/A_memorix/core/runtime/kernel_compat.py +269 -0
- src/A_memorix/core/runtime/lifecycle_orchestrator.py +368 -0
- src/A_memorix/core/runtime/models.py +27 -0
- src/A_memorix/core/runtime/runtime_facade.py +141 -0
- src/A_memorix/core/runtime/runtime_writer_lock.py +105 -0
- src/A_memorix/core/runtime/sdk_memory_kernel.py +1907 -0
- src/A_memorix/core/runtime/search_runtime_initializer.py +290 -0
- src/A_memorix/core/runtime/services/__init__.py +63 -0
- src/A_memorix/core/runtime/services/background_task_service.py +477 -0
- src/A_memorix/core/runtime/services/base.py +28 -0
- src/A_memorix/core/runtime/services/bundle_admin_service.py +2200 -0
- src/A_memorix/core/runtime/services/chat_filter_service.py +88 -0
- src/A_memorix/core/runtime/services/correction_admin_service.py +1274 -0
- src/A_memorix/core/runtime/services/delete_admin_service.py +2018 -0
- src/A_memorix/core/runtime/services/dual_vector_migration_service.py +109 -0
- src/A_memorix/core/runtime/services/dual_vector_state_service.py +503 -0
- src/A_memorix/core/runtime/services/embedding_state_service.py +515 -0
- src/A_memorix/core/runtime/services/episode_admin_service.py +104 -0
- src/A_memorix/core/runtime/services/fact_admin_service.py +199 -0
- src/A_memorix/core/runtime/services/feedback_correction_service.py +1523 -0
- src/A_memorix/core/runtime/services/graph_admin_service.py +1521 -0
- src/A_memorix/core/runtime/services/image_service.py +158 -0
- src/A_memorix/core/runtime/services/import_tuning_admin_service.py +158 -0
- src/A_memorix/core/runtime/services/ingest_service.py +787 -0
- src/A_memorix/core/runtime/services/memory_maintenance_service.py +404 -0
- src/A_memorix/core/runtime/services/memory_search_service.py +373 -0
- src/A_memorix/core/runtime/services/profile_admin_service.py +646 -0
- src/A_memorix/core/runtime/services/request_dedup_service.py +34 -0
- src/A_memorix/core/runtime/services/runtime_config_service.py +94 -0
- src/A_memorix/core/runtime/services/runtime_dependency_service.py +105 -0
- src/A_memorix/core/runtime/services/runtime_lifecycle_service.py +409 -0
- src/A_memorix/core/runtime/services/search_hit_processing_service.py +891 -0
- src/A_memorix/core/runtime/services/source_admin_service.py +52 -0
- src/A_memorix/core/runtime/services/stats_service.py +35 -0
- src/A_memorix/core/runtime/services/summary_service.py +50 -0
- src/A_memorix/core/runtime/services/v5_admin_service.py +326 -0
- src/A_memorix/core/runtime/services/vector_delete_service.py +30 -0
- src/A_memorix/core/runtime/services/vector_rebuild_checkpoint.py +65 -0
- src/A_memorix/core/runtime/services/vector_recovery_service.py +460 -0
- src/A_memorix/core/runtime/services/vector_runtime_service.py +1417 -0
- src/A_memorix/core/runtime/services/vector_space_service.py +251 -0
- src/A_memorix/core/storage/__init__.py +62 -0
- src/A_memorix/core/storage/format_migration.py +676 -0
- src/A_memorix/core/storage/graph_store.py +1733 -0
- src/A_memorix/core/storage/knowledge_types.py +183 -0
- src/A_memorix/core/storage/metadata_cleanup.py +913 -0
- src/A_memorix/core/storage/metadata_episode.py +1659 -0
- src/A_memorix/core/storage/metadata_fact.py +1410 -0
- src/A_memorix/core/storage/metadata_feedback.py +745 -0
- src/A_memorix/core/storage/metadata_fts.py +937 -0
- src/A_memorix/core/storage/metadata_image.py +1076 -0
- src/A_memorix/core/storage/metadata_profile.py +782 -0
- src/A_memorix/core/storage/metadata_schema.py +2503 -0
- src/A_memorix/core/storage/metadata_store.py +4565 -0
- src/A_memorix/core/storage/sqlite_connection.py +176 -0
- src/A_memorix/core/storage/tokenizer_runtime.py +9 -0
- src/A_memorix/core/storage/transaction.py +42 -0
- src/A_memorix/core/storage/type_detection.py +137 -0
- src/A_memorix/core/storage/value_coercion.py +10 -0
- src/A_memorix/core/storage/vector_store.py +2851 -0
- src/A_memorix/core/strategies/__init__.py +0 -0
- src/A_memorix/core/strategies/base.py +92 -0
- src/A_memorix/core/strategies/chat_log.py +80 -0
- src/A_memorix/core/strategies/factual.py +104 -0
- src/A_memorix/core/strategies/narrative.py +148 -0
- src/A_memorix/core/strategies/quote.py +47 -0
- src/A_memorix/core/utils/__init__.py +33 -0
- src/A_memorix/core/utils/aggregate_query_service.py +359 -0
- src/A_memorix/core/utils/episode_retrieval_service.py +222 -0
- src/A_memorix/core/utils/episode_segmentation_service.py +322 -0
- src/A_memorix/core/utils/episode_service.py +646 -0
- src/A_memorix/core/utils/feedback_policy.py +149 -0
- src/A_memorix/core/utils/hash.py +128 -0
- src/A_memorix/core/utils/import_payloads.py +222 -0
- src/A_memorix/core/utils/io.py +85 -0
- src/A_memorix/core/utils/matcher.py +175 -0
- src/A_memorix/core/utils/memory_lifecycle_policy.py +336 -0
- src/A_memorix/core/utils/metadata.py +11 -0
- src/A_memorix/core/utils/model_routing.py +239 -0
- src/A_memorix/core/utils/monitor.py +188 -0
- src/A_memorix/core/utils/path_fallback_service.py +182 -0
- src/A_memorix/core/utils/person_profile_service.py +1277 -0
- src/A_memorix/core/utils/plugin_id_policy.py +26 -0
- src/A_memorix/core/utils/profile_evidence.py +25 -0
- src/A_memorix/core/utils/profile_policy.py +45 -0
- src/A_memorix/core/utils/profile_text.py +204 -0
- src/A_memorix/core/utils/quantization.py +343 -0
- src/A_memorix/core/utils/relation_query.py +121 -0
- src/A_memorix/core/utils/relation_write_service.py +504 -0
- src/A_memorix/core/utils/retrieval_tuning_manager.py +2369 -0
- src/A_memorix/core/utils/runtime_payloads.py +132 -0
- src/A_memorix/core/utils/runtime_self_check.py +303 -0
- src/A_memorix/core/utils/search_execution_service.py +445 -0
- src/A_memorix/core/utils/search_postprocess.py +91 -0
- src/A_memorix/core/utils/summary_importer.py +991 -0
- src/A_memorix/core/utils/time_parser.py +156 -0
- src/A_memorix/core/utils/web_import_manager.py +4511 -0
- src/A_memorix/host_service.py +1018 -0
- src/A_memorix/paths.py +58 -0
- src/A_memorix/plugin.py +321 -0
- src/A_memorix/runtime_registry.py +30 -0
- src/A_memorix/scripts/_bootstrap.py +22 -0
- src/A_memorix/scripts/audit_vector_consistency.py +205 -0
- src/A_memorix/scripts/backfill_relation_vectors.py +265 -0
- src/A_memorix/scripts/backfill_temporal_metadata.py +67 -0
- src/A_memorix/scripts/convert_lpmm.py +537 -0
- src/A_memorix/scripts/import_lpmm_json.py +189 -0
- src/A_memorix/scripts/migrate_chat_history.py +101 -0
- src/A_memorix/scripts/migrate_maibot_memory.py +1955 -0
- src/A_memorix/scripts/migrate_person_memory_points.py +113 -0
- src/A_memorix/scripts/process_knowledge.py +831 -0
- src/A_memorix/scripts/rebuild_episodes.py +207 -0
- src/A_memorix/scripts/release_vnext_migrate.py +875 -0
- src/A_memorix/scripts/runtime_self_check.py +144 -0
- src/__init__.py +14 -0
- src/_resources/EULA.md +135 -0
- src/_resources/PRIVACY.md +60 -0
- src/_resources/changelogs/changelog.md +918 -0
- src/_resources/locales/en-US/config.json +39 -0
- src/_resources/locales/en-US/core.json +8 -0
- src/_resources/locales/en-US/prompts.json +8 -0
- src/_resources/locales/en-US/startup.json +98 -0
- src/_resources/locales/ja-JP/config.json +39 -0
- src/_resources/locales/ja-JP/core.json +8 -0
- src/_resources/locales/ja-JP/prompts.json +8 -0
- src/_resources/locales/ja-JP/startup.json +98 -0
- src/_resources/locales/ko/config.json +39 -0
- src/_resources/locales/ko/core.json +8 -0
- src/_resources/locales/ko/prompts.json +8 -0
- src/_resources/locales/ko/startup.json +98 -0
- src/_resources/locales/zh-CN/config.json +39 -0
- src/_resources/locales/zh-CN/core.json +8 -0
- src/_resources/locales/zh-CN/prompts.json +8 -0
- src/_resources/locales/zh-CN/startup.json +98 -0
- src/_resources/prompts/en-US/.meta.toml +164 -0
- src/_resources/prompts/en-US/a_memorix_chat_summary.prompt +45 -0
- src/_resources/prompts/en-US/emoji_content_analysis.prompt +3 -0
- src/_resources/prompts/en-US/emoji_content_filtration.prompt +6 -0
- src/_resources/prompts/en-US/emoji_replace.prompt +12 -0
- src/_resources/prompts/en-US/emoji_selection.prompt +6 -0
- src/_resources/prompts/en-US/expression_evaluation.prompt +14 -0
- src/_resources/prompts/en-US/heuristic_memory_impression.prompt +15 -0
- src/_resources/prompts/en-US/image_description.prompt +1 -0
- src/_resources/prompts/en-US/jargon_compare_inference.prompt +14 -0
- src/_resources/prompts/en-US/jargon_inference_content_only.prompt +11 -0
- src/_resources/prompts/en-US/jargon_inference_with_context.prompt +19 -0
- src/_resources/prompts/en-US/learn_jargon.prompt +31 -0
- src/_resources/prompts/en-US/learn_style.prompt +28 -0
- src/_resources/prompts/en-US/maisaka_chat.prompt +28 -0
- src/_resources/prompts/en-US/maisaka_chat_focus.prompt +39 -0
- src/_resources/prompts/en-US/maisaka_chat_optimized.prompt +19 -0
- src/_resources/prompts/en-US/maisaka_replyer.prompt +10 -0
- src/_resources/prompts/en-US/memory_fuzzy_modify_plan.prompt +45 -0
- src/_resources/prompts/en-US/mid_term_memory_summary.prompt +10 -0
- src/_resources/prompts/en-US/reply_attachments.prompt +3 -0
- src/_resources/prompts/en-US/retro_private_replyer.prompt +13 -0
- src/_resources/prompts/en-US/retro_private_replyer_self.prompt +13 -0
- src/_resources/prompts/en-US/retro_replyer.prompt +17 -0
- src/_resources/prompts/en-US/retro_replyer_light.prompt +17 -0
- src/_resources/prompts/en-US/webui_ai_search.prompt +24 -0
- src/_resources/prompts/en-US/webui_ai_search_correction.prompt +1 -0
- src/_resources/prompts/en-US/webui_ai_search_evidence.prompt +3 -0
- src/_resources/prompts/en-US/webui_ai_search_final.prompt +1 -0
- src/_resources/prompts/ja-JP/.meta.toml +164 -0
- src/_resources/prompts/ja-JP/a_memorix_chat_summary.prompt +45 -0
- src/_resources/prompts/ja-JP/emoji_content_analysis.prompt +3 -0
- src/_resources/prompts/ja-JP/emoji_content_filtration.prompt +6 -0
- src/_resources/prompts/ja-JP/emoji_replace.prompt +12 -0
- src/_resources/prompts/ja-JP/emoji_selection.prompt +6 -0
- src/_resources/prompts/ja-JP/expression_evaluation.prompt +14 -0
- src/_resources/prompts/ja-JP/heuristic_memory_impression.prompt +15 -0
- src/_resources/prompts/ja-JP/image_description.prompt +1 -0
- src/_resources/prompts/ja-JP/jargon_compare_inference.prompt +14 -0
- src/_resources/prompts/ja-JP/jargon_inference_content_only.prompt +11 -0
- src/_resources/prompts/ja-JP/jargon_inference_with_context.prompt +19 -0
- src/_resources/prompts/ja-JP/learn_jargon.prompt +31 -0
- src/_resources/prompts/ja-JP/learn_style.prompt +28 -0
- src/_resources/prompts/ja-JP/maisaka_chat.prompt +28 -0
- src/_resources/prompts/ja-JP/maisaka_chat_focus.prompt +39 -0
- src/_resources/prompts/ja-JP/maisaka_chat_optimized.prompt +19 -0
- src/_resources/prompts/ja-JP/maisaka_replyer.prompt +10 -0
- src/_resources/prompts/ja-JP/memory_fuzzy_modify_plan.prompt +45 -0
- src/_resources/prompts/ja-JP/mid_term_memory_summary.prompt +10 -0
- src/_resources/prompts/ja-JP/reply_attachments.prompt +3 -0
- src/_resources/prompts/ja-JP/retro_private_replyer.prompt +13 -0
- src/_resources/prompts/ja-JP/retro_private_replyer_self.prompt +13 -0
- src/_resources/prompts/ja-JP/retro_replyer.prompt +17 -0
- src/_resources/prompts/ja-JP/retro_replyer_light.prompt +17 -0
- src/_resources/prompts/ja-JP/webui_ai_search.prompt +24 -0
- src/_resources/prompts/ja-JP/webui_ai_search_correction.prompt +1 -0
- src/_resources/prompts/ja-JP/webui_ai_search_evidence.prompt +3 -0
- src/_resources/prompts/ja-JP/webui_ai_search_final.prompt +1 -0
- src/_resources/prompts/ko/.meta.toml +4 -0
- src/_resources/prompts/ko/reply_attachments.prompt +3 -0
- src/_resources/prompts/zh-CN/.meta.toml +159 -0
- src/_resources/prompts/zh-CN/a_memorix_chat_summary.prompt +59 -0
- src/_resources/prompts/zh-CN/emoji_content_analysis.prompt +3 -0
- src/_resources/prompts/zh-CN/emoji_content_filtration.prompt +6 -0
- src/_resources/prompts/zh-CN/emoji_replace.prompt +12 -0
- src/_resources/prompts/zh-CN/emoji_selection.prompt +6 -0
- src/_resources/prompts/zh-CN/expression_evaluation.prompt +14 -0
- src/_resources/prompts/zh-CN/heuristic_memory_impression.prompt +15 -0
- src/_resources/prompts/zh-CN/image_description.prompt +1 -0
- src/_resources/prompts/zh-CN/jargon_compare_inference.prompt +14 -0
- src/_resources/prompts/zh-CN/jargon_inference_content_only.prompt +11 -0
- src/_resources/prompts/zh-CN/jargon_inference_with_context.prompt +19 -0
- src/_resources/prompts/zh-CN/learn_jargon.prompt +31 -0
- src/_resources/prompts/zh-CN/learn_style.prompt +28 -0
- src/_resources/prompts/zh-CN/maisaka_chat.prompt +28 -0
- src/_resources/prompts/zh-CN/maisaka_chat_focus.prompt +39 -0
- src/_resources/prompts/zh-CN/maisaka_chat_optimized.prompt +19 -0
- src/_resources/prompts/zh-CN/maisaka_replyer.prompt +6 -0
- src/_resources/prompts/zh-CN/memory_fuzzy_modify_plan.prompt +45 -0
- src/_resources/prompts/zh-CN/mid_term_memory_summary.prompt +10 -0
- src/_resources/prompts/zh-CN/reply_attachments.prompt +3 -0
- src/_resources/prompts/zh-CN/retro_private_replyer.prompt +13 -0
- src/_resources/prompts/zh-CN/retro_private_replyer_self.prompt +13 -0
- src/_resources/prompts/zh-CN/retro_replyer.prompt +17 -0
- src/_resources/prompts/zh-CN/retro_replyer_light.prompt +17 -0
- src/_resources/prompts/zh-CN/webui_ai_search.prompt +24 -0
- src/_resources/prompts/zh-CN/webui_ai_search_correction.prompt +1 -0
- src/_resources/prompts/zh-CN/webui_ai_search_evidence.prompt +3 -0
- src/_resources/prompts/zh-CN/webui_ai_search_final.prompt +1 -0
- src/_resources/pyproject.toml +156 -0
- src/chat/__init__.py +13 -0
- src/chat/heart_flow/heartFC_utils.py +29 -0
- src/chat/heart_flow/heartflow_manager.py +138 -0
- src/chat/heart_flow/heartflow_message_processor.py +104 -0
- src/chat/image_system/image_cache_cleanup.py +300 -0
- src/chat/image_system/image_manager.py +516 -0
- src/chat/message_receive/__init__.py +5 -0
- src/chat/message_receive/bot.py +893 -0
- src/chat/message_receive/chat_manager.py +540 -0
- src/chat/message_receive/image_receive_compressor.py +135 -0
- src/chat/message_receive/message.py +546 -0
- src/chat/message_receive/uni_message_sender.py +332 -0
- src/chat/replyer/expression_vector_index.py +3176 -0
- src/chat/replyer/maisaka_expression_selector.py +678 -0
- src/chat/replyer/maisaka_generator.py +25 -0
- src/chat/replyer/maisaka_generator_base.py +1457 -0
- src/chat/replyer/replyer_manager.py +62 -0
- src/chat/replyer/retro_prompt.py +512 -0
- src/chat/utils/llm_sentence_splitter.py +151 -0
- src/chat/utils/statistic.py +3170 -0
- src/chat/utils/typo_generator.py +495 -0
- src/chat/utils/utils.py +922 -0
- src/cli/__init__.py +3 -0
- src/cli/bot_console.py +281 -0
- src/cli/console.py +17 -0
- src/cli/input_reader.py +55 -0
- src/cli/maisaka_cli.py +122 -0
- src/cli/maisaka_cli_sender.py +28 -0
- src/cli/tool.py +62 -0
- src/common/__init__.py +1 -0
- src/common/data_models/__init__.py +28 -0
- src/common/data_models/chat_session_data_model.py +73 -0
- src/common/data_models/chat_target_info_data_model.py +73 -0
- src/common/data_models/embedding_service_data_models.py +31 -0
- src/common/data_models/expression_data_model.py +83 -0
- src/common/data_models/image_data_model.py +247 -0
- src/common/data_models/jargon_data_model.py +101 -0
- src/common/data_models/llm_data_model.py +23 -0
- src/common/data_models/llm_service_data_models.py +298 -0
- src/common/data_models/mai_message_data_model.py +226 -0
- src/common/data_models/message_component_data_model.py +560 -0
- src/common/data_models/person_info_data_model.py +177 -0
- src/common/data_models/reply_generation_data_models.py +275 -0
- src/common/data_models/tool_record_data_model.py +51 -0
- src/common/database/__init__.py +0 -0
- src/common/database/database.py +240 -0
- src/common/database/database_model.py +477 -0
- src/common/database/migrations/__init__.py +161 -0
- src/common/database/migrations/behavior_generic_tags.py +532 -0
- src/common/database/migrations/bootstrap.py +171 -0
- src/common/database/migrations/builtin.py +1966 -0
- src/common/database/migrations/exceptions.py +33 -0
- src/common/database/migrations/frozen_v2_schema.py +282 -0
- src/common/database/migrations/legacy_v1_to_v2.py +1300 -0
- src/common/database/migrations/manager.py +209 -0
- src/common/database/migrations/models.py +305 -0
- src/common/database/migrations/planner.py +108 -0
- src/common/database/migrations/progress.py +319 -0
- src/common/database/migrations/registry.py +98 -0
- src/common/database/migrations/resolver.py +135 -0
- src/common/database/migrations/schema.py +98 -0
- src/common/database/migrations/v10_to_v11.py +60 -0
- src/common/database/migrations/v11_to_v12.py +92 -0
- src/common/database/migrations/v12_to_v13.py +42 -0
- src/common/database/migrations/v13_to_v14.py +55 -0
- src/common/database/migrations/v14_to_v15.py +44 -0
- src/common/database/migrations/v15_to_v16.py +39 -0
- src/common/database/migrations/v16_to_v17.py +66 -0
- src/common/database/migrations/v17_to_v18.py +64 -0
- src/common/database/migrations/v18_to_v19.py +355 -0
- src/common/database/migrations/v19_to_v20.py +169 -0
- src/common/database/migrations/v20_to_v21.py +149 -0
- src/common/database/migrations/v21_to_v22.py +343 -0
- src/common/database/migrations/v22_to_v23.py +114 -0
- src/common/database/migrations/v23_to_v24.py +465 -0
- src/common/database/migrations/v24_to_v25.py +96 -0
- src/common/database/migrations/v25_to_v26.py +32 -0
- src/common/database/migrations/v26_to_v27.py +86 -0
- src/common/database/migrations/v27_to_v28.py +185 -0
- src/common/database/migrations/v28_to_v29.py +80 -0
- src/common/database/migrations/v29_to_v30.py +217 -0
- src/common/database/migrations/v2_to_v3.py +269 -0
- src/common/database/migrations/v30_to_v31.py +323 -0
- src/common/database/migrations/v31_to_v32.py +250 -0
- src/common/database/migrations/v32_to_v33.py +84 -0
- src/common/database/migrations/v33_to_v34.py +119 -0
- src/common/database/migrations/v34_to_v35.py +68 -0
- src/common/database/migrations/v35_to_v36.py +35 -0
- src/common/database/migrations/v36_to_v37.py +54 -0
- src/common/database/migrations/v37_to_v38.py +95 -0
- src/common/database/migrations/v38_to_v39.py +85 -0
- src/common/database/migrations/v39_to_v40.py +53 -0
- src/common/database/migrations/v3_to_v4.py +155 -0
- src/common/database/migrations/v40_to_v41.py +23 -0
- src/common/database/migrations/v41_to_v42.py +44 -0
- src/common/database/migrations/v42_to_v43.py +29 -0
- src/common/database/migrations/v4_to_v5.py +77 -0
- src/common/database/migrations/v5_to_v6.py +51 -0
- src/common/database/migrations/v6_to_v7.py +164 -0
- src/common/database/migrations/v7_to_v8.py +73 -0
- src/common/database/migrations/v8_to_v9.py +313 -0
- src/common/database/migrations/v9_to_v10.py +53 -0
- src/common/database/migrations/version_store.py +57 -0
- src/common/embedding_identity.py +43 -0
- src/common/event_loop_watchdog.py +72 -0
- src/common/i18n/__init__.py +70 -0
- src/common/i18n/exceptions.py +18 -0
- src/common/i18n/formatting.py +29 -0
- src/common/i18n/loaders.py +162 -0
- src/common/i18n/manager.py +201 -0
- src/common/logger.py +1009 -0
- src/common/logger_color_and_mapping.py +430 -0
- src/common/message_repository.py +287 -0
- src/common/message_server/__init__.py +19 -0
- src/common/message_server/api.py +190 -0
- src/common/message_server/server.py +130 -0
- src/common/operation_timing.py +52 -0
- src/common/paths.py +32 -0
- src/common/process_runner.py +142 -0
- src/common/prompt_i18n.py +416 -0
- src/common/remote.py +288 -0
- src/common/reply_effect_fingerprint.py +119 -0
- src/common/reply_effect_record_codec.py +40 -0
- src/common/runtime_loop.py +31 -0
- src/common/self_update.py +580 -0
- src/common/shutdown.py +55 -0
- src/common/update_notice.py +351 -0
- src/common/utils/image_path.py +39 -0
- src/common/utils/math_utils.py +122 -0
- src/common/utils/port_checker.py +97 -0
- src/common/utils/system_utils.py +11 -0
- src/common/utils/utils_action.py +32 -0
- src/common/utils/utils_config.py +613 -0
- src/common/utils/utils_file.py +56 -0
- src/common/utils/utils_image.py +257 -0
- src/common/utils/utils_message.py +871 -0
- src/common/utils/utils_person.py +55 -0
- src/common/utils/utils_session.py +42 -0
- src/common/utils/utils_voice.py +42 -0
- src/common/version.py +33 -0
- src/config/__init__.py +0 -0
- src/config/config.py +927 -0
- src/config/config_base.py +308 -0
- src/config/config_upgrade_hooks.py +675 -0
- src/config/config_utils.py +166 -0
- src/config/default_model_config.py +131 -0
- src/config/file_watcher.py +238 -0
- src/config/legacy_migration.py +424 -0
- src/config/legacy_upgrade_confirmation.py +225 -0
- src/config/model_configs.py +548 -0
- src/config/official_configs.py +6166 -0
- src/config/startup_bindings.py +201 -0
- src/core/__init__.py +6 -0
- src/core/announcement_manager.py +120 -0
- src/core/config_types.py +273 -0
- src/core/event_bus.py +225 -0
- src/core/local_operator.py +98 -0
- src/core/tooling.py +420 -0
- src/core/types.py +423 -0
- src/emoji_system/emoji_cache_cleanup.py +326 -0
- src/emoji_system/emoji_manager.py +1314 -0
- src/emoji_system/maisaka_tool.py +286 -0
- src/learners/expression_learner.py +927 -0
- src/learners/expression_review_store.py +216 -0
- src/learners/expression_style_utils.py +32 -0
- src/learners/expression_utils.py +299 -0
- src/learners/jargon_learner.py +873 -0
- src/learners/jargon_miner.py +885 -0
- src/learners/weighted_sampling.py +75 -0
- src/llm_models/LICENSE +21 -0
- src/llm_models/__init__.py +0 -0
- src/llm_models/exceptions.py +140 -0
- src/llm_models/generation_diagnostics.py +155 -0
- src/llm_models/image_normalizer.py +128 -0
- src/llm_models/model_client/__init__.py +29 -0
- src/llm_models/model_client/adapter_base.py +362 -0
- src/llm_models/model_client/base_client.py +678 -0
- src/llm_models/model_client/embedding_rate_limit.py +55 -0
- src/llm_models/model_client/gemini_client.py +1379 -0
- src/llm_models/model_client/image_embedding_protocols.py +397 -0
- src/llm_models/model_client/openai_client.py +2200 -0
- src/llm_models/model_client/openai_responses_client.py +817 -0
- src/llm_models/model_client/plugin_client.py +307 -0
- src/llm_models/openai_compat.py +165 -0
- src/llm_models/payload_content/__init__.py +51 -0
- src/llm_models/payload_content/context_item.py +699 -0
- src/llm_models/payload_content/context_protocol.py +243 -0
- src/llm_models/payload_content/native_tool.py +18 -0
- src/llm_models/payload_content/resp_format.py +239 -0
- src/llm_models/payload_content/tool_option.py +547 -0
- src/llm_models/request_snapshot.py +1311 -0
- src/llm_models/utils.py +276 -0
- src/llm_models/utils_model.py +1604 -0
- src/main.py +300 -0
- src/maisaka/attention_drift.py +116 -0
- src/maisaka/builtin_tool/__init__.py +236 -0
- src/maisaka/builtin_tool/context.py +530 -0
- src/maisaka/builtin_tool/fetch_history.py +62 -0
- src/maisaka/builtin_tool/provider.py +74 -0
- src/maisaka/builtin_tool/query_image_memory.py +103 -0
- src/maisaka/builtin_tool/query_memory.py +335 -0
- src/maisaka/builtin_tool/query_person_profile.py +152 -0
- src/maisaka/builtin_tool/read_tool_result.py +142 -0
- src/maisaka/builtin_tool/reply.py +695 -0
- src/maisaka/builtin_tool/send_emoji.py +543 -0
- src/maisaka/builtin_tool/show_emoji_list.py +76 -0
- src/maisaka/builtin_tool/subagent.py +549 -0
- src/maisaka/builtin_tool/switch_chat.py +78 -0
- src/maisaka/builtin_tool/tool_search.py +92 -0
- src/maisaka/builtin_tool/view_forward_message.py +153 -0
- src/maisaka/builtin_tool/wait.py +77 -0
- src/maisaka/chat_loop_service.py +1579 -0
- src/maisaka/context/__init__.py +1 -0
- src/maisaka/context/clear_context.py +42 -0
- src/maisaka/context/emoji_candidates.py +36 -0
- src/maisaka/context/history.py +384 -0
- src/maisaka/context/image_attachment.py +52 -0
- src/maisaka/context/message_adapter.py +126 -0
- src/maisaka/context/message_id_alias.py +52 -0
- src/maisaka/context/messages.py +825 -0
- src/maisaka/context/planner_messages.py +199 -0
- src/maisaka/context/post_processor.py +204 -0
- src/maisaka/context/usage.py +141 -0
- src/maisaka/display/__init__.py +25 -0
- src/maisaka/display/display_utils.py +144 -0
- src/maisaka/display/preview_path_utils.py +64 -0
- src/maisaka/display/prompt_cli_renderer.py +1110 -0
- src/maisaka/display/prompt_preview_logger.py +603 -0
- src/maisaka/display/runtime_mixin.py +709 -0
- src/maisaka/display/stage_status_board.py +129 -0
- src/maisaka/focus/__init__.py +10 -0
- src/maisaka/focus/manager.py +442 -0
- src/maisaka/focus/runtime_mixin.py +753 -0
- src/maisaka/jargon_context_matcher.py +363 -0
- src/maisaka/memory/__init__.py +1 -0
- src/maisaka/memory/heuristic_injector.py +393 -0
- src/maisaka/memory/image_injector.py +81 -0
- src/maisaka/memory/mid_term.py +995 -0
- src/maisaka/memory/person_profile.py +280 -0
- src/maisaka/mode_policy.py +28 -0
- src/maisaka/monitor/__init__.py +1 -0
- src/maisaka/monitor/event_store.py +351 -0
- src/maisaka/monitor/events.py +795 -0
- src/maisaka/monitor/message_payload.py +172 -0
- src/maisaka/monitor/planner_delta.py +77 -0
- src/maisaka/monitor/tool_media.py +58 -0
- src/maisaka/planner_reply_guard.py +69 -0
- src/maisaka/reasoning_engine.py +2186 -0
- src/maisaka/reply_effect/__init__.py +18 -0
- src/maisaka/reply_effect/image_utils.py +100 -0
- src/maisaka/reply_effect/judge.py +382 -0
- src/maisaka/reply_effect/models.py +185 -0
- src/maisaka/reply_effect/path_utils.py +24 -0
- src/maisaka/reply_effect/quote_utils.py +32 -0
- src/maisaka/reply_effect/scoring.py +205 -0
- src/maisaka/reply_effect/storage.py +380 -0
- src/maisaka/reply_effect/tracker.py +568 -0
- src/maisaka/runtime.py +2218 -0
- src/maisaka/subagent_tasks.py +171 -0
- src/maisaka/tool_result_condenser.py +143 -0
- src/maisaka/tool_result_store.py +57 -0
- src/maisaka/turn_trigger/__init__.py +9 -0
- src/maisaka/turn_trigger/dynamic_gate.py +211 -0
- src/maisaka/turn_trigger/gates.py +252 -0
- src/maisaka/turn_trigger/idle_backoff.py +93 -0
- src/maisaka/turn_trigger/reply_likelihood.py +88 -0
- src/maisaka/turn_trigger/scheduler.py +113 -0
- src/maisaka/utils/__init__.py +1 -0
- src/maisaka/utils/tool_post_execution.py +76 -0
- src/maisaka/utils/tool_record_payload.py +155 -0
- src/maisaka/visual/__init__.py +1 -0
- src/maisaka/visual/chat_history_refresher.py +303 -0
- src/maisaka/visual/message_limiter.py +69 -0
- src/maisaka/visual/mode_utils.py +33 -0
- src/manager/async_task_manager.py +193 -0
- src/manager/local_store_manager.py +126 -0
- src/mcp_module/__init__.py +9 -0
- src/mcp_module/config.py +174 -0
- src/mcp_module/connection.py +726 -0
- src/mcp_module/hooks.py +20 -0
- src/mcp_module/host_llm_bridge.py +654 -0
- src/mcp_module/manager.py +680 -0
- src/mcp_module/models.py +437 -0
- src/mcp_module/provider.py +62 -0
- src/mcp_module/service.py +308 -0
- src/mcp_module/stdio_filter.py +177 -0
- src/person_info/__init__.py +0 -0
- src/person_info/person_info.py +600 -0
- src/platform_io/__init__.py +39 -0
- src/platform_io/adapter_policy.py +839 -0
- src/platform_io/avatar.py +197 -0
- src/platform_io/dedupe.py +133 -0
- src/platform_io/drivers/__init__.py +11 -0
- src/platform_io/drivers/base.py +104 -0
- src/platform_io/drivers/legacy_driver.py +92 -0
- src/platform_io/drivers/plugin_driver.py +213 -0
- src/platform_io/manager.py +716 -0
- src/platform_io/outbound_tracker.py +286 -0
- src/platform_io/registry.py +70 -0
- src/platform_io/route_key_factory.py +174 -0
- src/platform_io/routing.py +141 -0
- src/platform_io/types.py +265 -0
- src/plugin_runtime/__init__.py +60 -0
- src/plugin_runtime/avatar_provider.py +64 -0
- src/plugin_runtime/capabilities/__init__.py +11 -0
- src/plugin_runtime/capabilities/components.py +977 -0
- src/plugin_runtime/capabilities/core.py +868 -0
- src/plugin_runtime/capabilities/data.py +1415 -0
- src/plugin_runtime/capabilities/registry.py +116 -0
- src/plugin_runtime/capabilities/render.py +131 -0
- src/plugin_runtime/compat_policy.py +47 -0
- src/plugin_runtime/component_query.py +1119 -0
- src/plugin_runtime/dependency_pipeline.py +547 -0
- src/plugin_runtime/docker_layout_migration.py +275 -0
- src/plugin_runtime/hook_catalog.py +52 -0
- src/plugin_runtime/hook_payloads.py +197 -0
- src/plugin_runtime/hook_schema_utils.py +31 -0
- src/plugin_runtime/host/__init__.py +1 -0
- src/plugin_runtime/host/api_registry.py +353 -0
- src/plugin_runtime/host/authorization.py +67 -0
- src/plugin_runtime/host/capability_service.py +91 -0
- src/plugin_runtime/host/circuit_breaker.py +243 -0
- src/plugin_runtime/host/component_registry.py +1336 -0
- src/plugin_runtime/host/component_timeout.py +32 -0
- src/plugin_runtime/host/event_dispatcher.py +228 -0
- src/plugin_runtime/host/hook_dispatcher.py +711 -0
- src/plugin_runtime/host/hook_spec_registry.py +190 -0
- src/plugin_runtime/host/logger_bridge.py +64 -0
- src/plugin_runtime/host/message_gateway.py +116 -0
- src/plugin_runtime/host/message_utils.py +572 -0
- src/plugin_runtime/host/reply_extension_schema.py +65 -0
- src/plugin_runtime/host/reply_extensions.py +204 -0
- src/plugin_runtime/host/rpc_server.py +509 -0
- src/plugin_runtime/host/supervisor.py +2269 -0
- src/plugin_runtime/integration.py +2063 -0
- src/plugin_runtime/local_sdk.py +147 -0
- src/plugin_runtime/protocol/__init__.py +1 -0
- src/plugin_runtime/protocol/codec.py +71 -0
- src/plugin_runtime/protocol/envelope.py +600 -0
- src/plugin_runtime/protocol/errors.py +77 -0
- src/plugin_runtime/runner/__init__.py +1 -0
- src/plugin_runtime/runner/log_handler.py +239 -0
- src/plugin_runtime/runner/manifest_validator.py +1517 -0
- src/plugin_runtime/runner/plugin_loader.py +711 -0
- src/plugin_runtime/runner/plugin_paths.py +59 -0
- src/plugin_runtime/runner/rpc_client.py +336 -0
- src/plugin_runtime/runner/runner_main.py +2670 -0
- src/plugin_runtime/tool_provider.py +58 -0
- src/plugin_runtime/transport/__init__.py +1 -0
- src/plugin_runtime/transport/base.py +116 -0
- src/plugin_runtime/transport/factory.py +57 -0
- src/plugin_runtime/transport/named_pipe.py +206 -0
- src/plugin_runtime/transport/tcp.py +62 -0
- src/plugin_runtime/transport/uds.py +133 -0
- src/plugin_runtime/update_compatibility_notice.py +303 -0
- src/plugin_runtime/upload_store.py +173 -0
- src/plugin_runtime/webui_schema.py +571 -0
- src/plugins/__init__.py +1 -0
- src/plugins/built_in/plugin_management/_manifest.json +48 -0
- src/plugins/built_in/plugin_management/plugin.py +665 -0
- src/prompt/prompt_manager.py +440 -0
- src/runtime.py +688 -0
- src/services/__init__.py +7 -0
- src/services/bot_account_service.py +327 -0
- src/services/database_service.py +203 -0
- src/services/embedding_service.py +271 -0
- src/services/expression_vector_service.py +106 -0
- src/services/html_render_service.py +945 -0
- src/services/image_path_maintenance_service.py +454 -0
- src/services/image_writeback_journal.py +98 -0
- src/services/llm_cache_stats.py +1521 -0
- src/services/llm_service.py +799 -0
- src/services/memory_flow_service.py +1019 -0
- src/services/memory_service.py +528 -0
- src/services/message_service.py +295 -0
- src/services/message_word_frequency_service.py +595 -0
- src/services/news_service.py +123 -0
- src/services/person_fact_reverification.py +90 -0
- src/services/person_fact_verifier.py +79 -0
- src/services/send_service.py +1483 -0
- src/services/service_task_resolver.py +59 -0
- src/services/statistics_aggregation_service.py +349 -0
- src/services/statistics_service.py +850 -0
- src/services/telemetry_stats_service.py +294 -0
- src/services/tool_record_cleanup_service.py +205 -0
- src/webui/app.py +374 -0
- src/webui/config_schema.py +481 -0
- src/webui/core/__init__.py +32 -0
- src/webui/core/auth.py +153 -0
- src/webui/core/rate_limiter.py +247 -0
- src/webui/core/security.py +361 -0
- src/webui/dependencies.py +70 -0
- src/webui/logs_ws.py +195 -0
- src/webui/middleware/__init__.py +17 -0
- src/webui/middleware/anti_crawler.py +824 -0
- src/webui/middleware/compression.py +88 -0
- src/webui/routers/__init__.py +33 -0
- src/webui/routers/avatar.py +250 -0
- src/webui/routers/bot_accounts.py +103 -0
- src/webui/routers/chat/__init__.py +18 -0
- src/webui/routers/chat/routes.py +1715 -0
- src/webui/routers/chat/serializers.py +248 -0
- src/webui/routers/chat/service.py +1489 -0
- src/webui/routers/config.py +1964 -0
- src/webui/routers/data_transfer.py +769 -0
- src/webui/routers/emoji/__init__.py +3 -0
- src/webui/routers/emoji/routes.py +1230 -0
- src/webui/routers/emoji/schemas.py +182 -0
- src/webui/routers/emoji/support.py +143 -0
- src/webui/routers/expression.py +2298 -0
- src/webui/routers/jargon.py +1319 -0
- src/webui/routers/mcp.py +99 -0
- src/webui/routers/memory.py +5589 -0
- src/webui/routers/model.py +910 -0
- src/webui/routers/news.py +23 -0
- src/webui/routers/person.py +427 -0
- src/webui/routers/plugin/__init__.py +31 -0
- src/webui/routers/plugin/catalog.py +218 -0
- src/webui/routers/plugin/config_routes.py +592 -0
- src/webui/routers/plugin/icon_routes.py +71 -0
- src/webui/routers/plugin/management.py +908 -0
- src/webui/routers/plugin/marketplace.py +116 -0
- src/webui/routers/plugin/progress.py +172 -0
- src/webui/routers/plugin/release_install.py +313 -0
- src/webui/routers/plugin/releases.py +181 -0
- src/webui/routers/plugin/runtime_routes.py +243 -0
- src/webui/routers/plugin/schemas.py +131 -0
- src/webui/routers/plugin/stats_proxy.py +127 -0
- src/webui/routers/plugin/support.py +366 -0
- src/webui/routers/plugin/webui_extensions.py +346 -0
- src/webui/routers/plugin/zip_install.py +125 -0
- src/webui/routers/reasoning_process.py +2326 -0
- src/webui/routers/reply_effects.py +926 -0
- src/webui/routers/search.py +249 -0
- src/webui/routers/self_update.py +194 -0
- src/webui/routers/statistics.py +61 -0
- src/webui/routers/system.py +1790 -0
- src/webui/routers/user_emoji.py +168 -0
- src/webui/routers/websocket/__init__.py +7 -0
- src/webui/routers/websocket/auth.py +104 -0
- src/webui/routers/websocket/manager.py +373 -0
- src/webui/routers/websocket/plugin_runtime.py +54 -0
- src/webui/routers/websocket/unified.py +761 -0
- src/webui/routes.py +416 -0
- src/webui/schemas/__init__.py +18 -0
- src/webui/schemas/news.py +24 -0
- src/webui/schemas/statistics.py +173 -0
- src/webui/services/__init__.py +1 -0
- src/webui/services/ai_search_agent.py +509 -0
- src/webui/services/ai_search_documents.py +329 -0
- src/webui/services/ai_search_grounding.py +103 -0
- src/webui/services/ai_search_local_config.py +129 -0
- src/webui/services/ai_search_models.py +98 -0
- src/webui/services/git_mirror_service.py +1024 -0
- src/webui/services/plugin_market_service.py +56 -0
- src/webui/utils/__init__.py +1 -0
- src/webui/utils/http_client.py +27 -0
- src/webui/utils/network_security.py +133 -0
- src/webui/utils/toml_utils.py +124 -0
- src/webui/version_compatibility.py +180 -0
- src/webui/webui_server.py +422 -0
src/main.py
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
2
|
+
|
|
3
|
+
from rich.traceback import install
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import sys
|
|
7
|
+
import time
|
|
8
|
+
|
|
9
|
+
from src.common.i18n import t
|
|
10
|
+
from src.common.logger import get_logger
|
|
11
|
+
from src.common.runtime_loop import set_main_loop
|
|
12
|
+
from src.config.config import config_manager, global_config
|
|
13
|
+
from src.manager.async_task_manager import async_task_manager
|
|
14
|
+
from src.prompt.prompt_manager import prompt_manager
|
|
15
|
+
|
|
16
|
+
# from src.api.main import start_api_server
|
|
17
|
+
|
|
18
|
+
# 导入插件运行时
|
|
19
|
+
# 导入消息API和traceback模块
|
|
20
|
+
# from src.chat.utils.token_statistics import TokenStatisticsTask
|
|
21
|
+
|
|
22
|
+
install(extra_lines=3)
|
|
23
|
+
|
|
24
|
+
logger = get_logger("main")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from maim_message import MessageServer
|
|
29
|
+
from src.common.message_server.server import Server
|
|
30
|
+
from src.webui.webui_server import ThreadedWebUIServer
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
async def _wait_for_plugin_runners_spawned(
|
|
34
|
+
plugin_runtime_manager: Any,
|
|
35
|
+
plugin_runtime_task: asyncio.Task[None],
|
|
36
|
+
timeout: float = 1.0,
|
|
37
|
+
) -> None:
|
|
38
|
+
"""让插件 Runner 子进程先拉起,以便和后续重初始化并行。"""
|
|
39
|
+
|
|
40
|
+
deadline = asyncio.get_running_loop().time() + timeout
|
|
41
|
+
while not plugin_runtime_task.done():
|
|
42
|
+
supervisors = list(getattr(plugin_runtime_manager, "supervisors", []))
|
|
43
|
+
if supervisors and all(getattr(supervisor, "_runner_process", None) is not None for supervisor in supervisors):
|
|
44
|
+
return
|
|
45
|
+
if asyncio.get_running_loop().time() >= deadline:
|
|
46
|
+
return
|
|
47
|
+
await asyncio.sleep(0.02)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class MainSystem:
|
|
51
|
+
def __init__(self) -> None:
|
|
52
|
+
# 使用消息API替代直接的FastAPI实例
|
|
53
|
+
self.app: MessageServer | None = None
|
|
54
|
+
self.server: Server | None = None
|
|
55
|
+
self.webui_server: ThreadedWebUIServer | None = None # 独立线程中的 WebUI 服务器
|
|
56
|
+
self._message_handlers_registered = False
|
|
57
|
+
self.watchdog_task: Optional[asyncio.Task[None]] = None
|
|
58
|
+
|
|
59
|
+
def _ensure_message_server(self) -> None:
|
|
60
|
+
"""按需初始化消息 API,避免阻塞主启动链路的早期阶段。"""
|
|
61
|
+
|
|
62
|
+
if self.app is not None and self.server is not None:
|
|
63
|
+
return
|
|
64
|
+
|
|
65
|
+
from src.common.message_server import get_global_api
|
|
66
|
+
from src.common.message_server.server import get_global_server
|
|
67
|
+
|
|
68
|
+
self.app = get_global_api()
|
|
69
|
+
self.server = get_global_server()
|
|
70
|
+
|
|
71
|
+
def _register_message_handlers(self) -> None:
|
|
72
|
+
"""注册主消息处理器;消息服务实际调度前完成即可。"""
|
|
73
|
+
|
|
74
|
+
if self._message_handlers_registered:
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
self._ensure_message_server()
|
|
78
|
+
if self.app is None:
|
|
79
|
+
raise RuntimeError("消息 API 初始化失败")
|
|
80
|
+
|
|
81
|
+
from src.chat.message_receive.bot import chat_bot
|
|
82
|
+
|
|
83
|
+
self.app.register_message_handler(chat_bot.message_process)
|
|
84
|
+
self.app.register_custom_message_handler("message_id_echo", chat_bot.echo_message_process)
|
|
85
|
+
self._message_handlers_registered = True
|
|
86
|
+
|
|
87
|
+
def _start_webui_server(self) -> None:
|
|
88
|
+
"""启动独立线程中的 WebUI 服务器。"""
|
|
89
|
+
from src.config.config import global_config
|
|
90
|
+
|
|
91
|
+
if not global_config.webui.enabled:
|
|
92
|
+
logger.info(t("startup.webui_disabled"))
|
|
93
|
+
return
|
|
94
|
+
|
|
95
|
+
try:
|
|
96
|
+
from src.webui.webui_server import get_threaded_webui_server
|
|
97
|
+
|
|
98
|
+
self.webui_server = get_threaded_webui_server()
|
|
99
|
+
self.webui_server.start()
|
|
100
|
+
|
|
101
|
+
except Exception as e:
|
|
102
|
+
logger.error(t("startup.webui_server_init_failed", error=e))
|
|
103
|
+
|
|
104
|
+
async def initialize(self) -> None:
|
|
105
|
+
"""初始化系统组件"""
|
|
106
|
+
logger.info(t("startup.waking_up", nickname=global_config.bot.nickname))
|
|
107
|
+
|
|
108
|
+
try:
|
|
109
|
+
from src.services.tool_record_cleanup_service import run_startup_tool_record_vacuum_if_needed
|
|
110
|
+
|
|
111
|
+
await asyncio.to_thread(run_startup_tool_record_vacuum_if_needed)
|
|
112
|
+
await self._init_components()
|
|
113
|
+
except Exception:
|
|
114
|
+
if self.webui_server:
|
|
115
|
+
await self.webui_server.shutdown()
|
|
116
|
+
raise
|
|
117
|
+
|
|
118
|
+
logger.info(t("startup.initialization_completed_banner", nickname=global_config.bot.nickname))
|
|
119
|
+
|
|
120
|
+
async def _init_components(self) -> None:
|
|
121
|
+
"""初始化其他组件"""
|
|
122
|
+
init_start_time = time.time()
|
|
123
|
+
|
|
124
|
+
await config_manager.start_file_watcher()
|
|
125
|
+
|
|
126
|
+
# 插件 Runner 启动最重,尽早发起以便和后续初始化并行。
|
|
127
|
+
from src.plugin_runtime.integration import get_plugin_runtime_manager
|
|
128
|
+
|
|
129
|
+
plugin_runtime_manager = get_plugin_runtime_manager()
|
|
130
|
+
plugin_runtime_task = asyncio.create_task(plugin_runtime_manager.start(), name="plugin_runtime_start")
|
|
131
|
+
await _wait_for_plugin_runners_spawned(plugin_runtime_manager, plugin_runtime_task)
|
|
132
|
+
|
|
133
|
+
# 数据库启动维护已完成;让 WebUI 在线程中加载,与后续组件初始化并行,
|
|
134
|
+
# 无需等待全部插件就绪后才开放管理页面。
|
|
135
|
+
self._start_webui_server()
|
|
136
|
+
|
|
137
|
+
from src.A_memorix.host_service import a_memorix_host_service
|
|
138
|
+
from src.mcp_module.service import get_mcp_service
|
|
139
|
+
from src.services.expression_vector_service import expression_vector_service
|
|
140
|
+
|
|
141
|
+
a_memorix_host_service.register_config_reload_callback()
|
|
142
|
+
get_mcp_service().register_config_reload_callback()
|
|
143
|
+
expression_vector_service.start()
|
|
144
|
+
a_memorix_task = asyncio.create_task(a_memorix_host_service.start(), name="a_memorix_start")
|
|
145
|
+
|
|
146
|
+
await asyncio.sleep(0)
|
|
147
|
+
prompt_manager.load_prompts()
|
|
148
|
+
|
|
149
|
+
from src.emoji_system.emoji_manager import emoji_manager
|
|
150
|
+
|
|
151
|
+
emoji_load_task = asyncio.create_task(asyncio.to_thread(emoji_manager.load_emojis_from_db), name="emoji_load_from_db")
|
|
152
|
+
|
|
153
|
+
# 启动API服务器
|
|
154
|
+
# start_api_server()
|
|
155
|
+
# logger.info("API服务器启动成功")
|
|
156
|
+
|
|
157
|
+
try:
|
|
158
|
+
await asyncio.gather(plugin_runtime_task, a_memorix_task)
|
|
159
|
+
await emoji_load_task
|
|
160
|
+
except Exception:
|
|
161
|
+
for task in (plugin_runtime_task, a_memorix_task, emoji_load_task):
|
|
162
|
+
if not task.done():
|
|
163
|
+
task.cancel()
|
|
164
|
+
await asyncio.gather(
|
|
165
|
+
plugin_runtime_task,
|
|
166
|
+
a_memorix_task,
|
|
167
|
+
emoji_load_task,
|
|
168
|
+
return_exceptions=True,
|
|
169
|
+
)
|
|
170
|
+
raise
|
|
171
|
+
|
|
172
|
+
# 初始化表情管理器
|
|
173
|
+
logger.info(t("startup.emoji_manager_initialized"))
|
|
174
|
+
|
|
175
|
+
# 初始化聊天管理器
|
|
176
|
+
from src.chat.message_receive.chat_manager import chat_manager
|
|
177
|
+
from src.services.memory_flow_service import memory_automation_service
|
|
178
|
+
|
|
179
|
+
await chat_manager.initialize()
|
|
180
|
+
asyncio.create_task(chat_manager.regularly_save_sessions())
|
|
181
|
+
|
|
182
|
+
logger.info(t("startup.chat_manager_initialized"))
|
|
183
|
+
await memory_automation_service.start()
|
|
184
|
+
|
|
185
|
+
# await asyncio.sleep(0.5) #防止logger输出飞了
|
|
186
|
+
|
|
187
|
+
# 触发 ON_START 事件,事件总线会统一桥接到 IPC 插件运行时。
|
|
188
|
+
from src.core.event_bus import event_bus
|
|
189
|
+
from src.core.types import EventType
|
|
190
|
+
|
|
191
|
+
await event_bus.emit(event_type=EventType.ON_START)
|
|
192
|
+
# logger.info("已触发 ON_START 事件")
|
|
193
|
+
|
|
194
|
+
from src.chat.utils.statistic import OnlineTimeRecordTask, StatisticOutputTask
|
|
195
|
+
|
|
196
|
+
# 添加在线时间统计任务
|
|
197
|
+
await async_task_manager.add_task(OnlineTimeRecordTask())
|
|
198
|
+
|
|
199
|
+
# 添加统计信息输出任务
|
|
200
|
+
await async_task_manager.add_task(StatisticOutputTask())
|
|
201
|
+
|
|
202
|
+
# 添加遥测心跳与统计上传任务
|
|
203
|
+
from src.common.remote import TelemetryHeartBeatTask, TelemetryStatsUploadTask
|
|
204
|
+
|
|
205
|
+
await async_task_manager.add_task(TelemetryHeartBeatTask())
|
|
206
|
+
await async_task_manager.add_task(TelemetryStatsUploadTask())
|
|
207
|
+
|
|
208
|
+
# 主循环卡顿看门狗;WebUI 循环另有一份,挂在 WebUI 服务器启动处。
|
|
209
|
+
from src.common.event_loop_watchdog import start_watchdog
|
|
210
|
+
|
|
211
|
+
self.watchdog_task = start_watchdog("main")
|
|
212
|
+
|
|
213
|
+
try:
|
|
214
|
+
init_time = int(1000 * (time.time() - init_start_time))
|
|
215
|
+
logger.info(t("startup.initialization_completed_cycles", init_time=init_time))
|
|
216
|
+
except Exception as e:
|
|
217
|
+
logger.error(t("startup.brain_external_world_failed", error=e))
|
|
218
|
+
raise
|
|
219
|
+
|
|
220
|
+
async def schedule_tasks(self) -> None:
|
|
221
|
+
"""调度定时任务"""
|
|
222
|
+
try:
|
|
223
|
+
from src.chat.image_system.image_cache_cleanup import periodic_image_cache_cleanup
|
|
224
|
+
from src.emoji_system.emoji_cache_cleanup import periodic_emoji_cache_cleanup
|
|
225
|
+
from src.emoji_system.emoji_manager import emoji_manager
|
|
226
|
+
from src.maisaka.display.prompt_preview_logger import PromptPreviewLogger
|
|
227
|
+
from src.services.image_path_maintenance_service import (
|
|
228
|
+
run_image_path_maintenance_background,
|
|
229
|
+
should_schedule_image_path_maintenance_background,
|
|
230
|
+
)
|
|
231
|
+
from src.webui.routers.data_transfer import periodic_transfer_temp_cleanup
|
|
232
|
+
|
|
233
|
+
# 在独立线程中巡检推理图片,空闲时也能清理旧版本遗留的孤立缓存。
|
|
234
|
+
PromptPreviewLogger.start()
|
|
235
|
+
self._register_message_handlers()
|
|
236
|
+
if self.app is None or self.server is None:
|
|
237
|
+
raise RuntimeError("消息服务未初始化")
|
|
238
|
+
|
|
239
|
+
tasks = [
|
|
240
|
+
emoji_manager.periodic_emoji_maintenance(),
|
|
241
|
+
periodic_emoji_cache_cleanup(),
|
|
242
|
+
periodic_image_cache_cleanup(),
|
|
243
|
+
periodic_transfer_temp_cleanup(),
|
|
244
|
+
self.app.run(),
|
|
245
|
+
self.server.run(),
|
|
246
|
+
]
|
|
247
|
+
if global_config.debug.enable_console_input:
|
|
248
|
+
if sys.stdin.isatty():
|
|
249
|
+
from src.cli.bot_console import BotConsole
|
|
250
|
+
|
|
251
|
+
logger.info("已启用终端输入,可输入普通消息或 /clear、/pm 等指令;输入 exit() 关闭终端输入")
|
|
252
|
+
tasks.append(BotConsole().run())
|
|
253
|
+
else:
|
|
254
|
+
logger.warning("终端输入已配置为启用,但当前 stdin 不是交互式终端,已跳过")
|
|
255
|
+
image_path_maintenance_needed = await asyncio.to_thread(should_schedule_image_path_maintenance_background)
|
|
256
|
+
if image_path_maintenance_needed:
|
|
257
|
+
tasks.append(run_image_path_maintenance_background())
|
|
258
|
+
|
|
259
|
+
await asyncio.gather(*tasks)
|
|
260
|
+
except asyncio.CancelledError:
|
|
261
|
+
logger.info(t("startup.schedule_cancelled"))
|
|
262
|
+
raise
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
async def main() -> None:
|
|
266
|
+
"""主函数"""
|
|
267
|
+
set_main_loop(asyncio.get_running_loop())
|
|
268
|
+
system = MainSystem()
|
|
269
|
+
try:
|
|
270
|
+
await system.initialize()
|
|
271
|
+
await system.schedule_tasks()
|
|
272
|
+
finally:
|
|
273
|
+
if system.webui_server:
|
|
274
|
+
await system.webui_server.shutdown()
|
|
275
|
+
if system.watchdog_task is not None:
|
|
276
|
+
system.watchdog_task.cancel()
|
|
277
|
+
system.watchdog_task = None
|
|
278
|
+
from src.A_memorix.host_service import a_memorix_host_service
|
|
279
|
+
from src.chat.image_system.image_manager import image_manager
|
|
280
|
+
from src.emoji_system.emoji_manager import emoji_manager
|
|
281
|
+
from src.mcp_module.service import get_mcp_service
|
|
282
|
+
from src.plugin_runtime.integration import get_plugin_runtime_manager
|
|
283
|
+
from src.services.expression_vector_service import expression_vector_service
|
|
284
|
+
from src.services.memory_flow_service import memory_automation_service
|
|
285
|
+
|
|
286
|
+
emoji_manager.shutdown()
|
|
287
|
+
await image_manager.shutdown()
|
|
288
|
+
await expression_vector_service.stop()
|
|
289
|
+
await memory_automation_service.shutdown()
|
|
290
|
+
await a_memorix_host_service.stop()
|
|
291
|
+
await get_plugin_runtime_manager().bridge_event("on_stop")
|
|
292
|
+
await get_plugin_runtime_manager().stop()
|
|
293
|
+
await async_task_manager.stop_and_wait_all_tasks()
|
|
294
|
+
await get_mcp_service().close()
|
|
295
|
+
await config_manager.stop_file_watcher()
|
|
296
|
+
set_main_loop(None)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
if __name__ == "__main__":
|
|
300
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
from typing import Mapping
|
|
2
|
+
|
|
3
|
+
from src.common.i18n import get_locale
|
|
4
|
+
from src.config.config import global_config
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
DRIFT_LEVEL_RULES = {
|
|
8
|
+
"subtle": {
|
|
9
|
+
"zh-CN": "漂移档位:轻微漂移。只在最近消息里出现非常自然的触发点时,轻轻联想一句;大多数时候继续当前话题。",
|
|
10
|
+
"en-US": "Drift level: subtle. Add a small aside only when recent messages provide a very natural hook; usually stay on the current topic.",
|
|
11
|
+
"ja-JP": "ドリフト段階:軽め。直近メッセージにとても自然なきっかけがある時だけ軽く一言連想し、基本は現在の話題に沿ってください。",
|
|
12
|
+
},
|
|
13
|
+
"active": {
|
|
14
|
+
"zh-CN": "漂移档位:活跃联想。可以主动抓住新鲜、好笑、反差强或熟悉的细节接话,但回复仍要清楚、短促、能被最近消息解释。",
|
|
15
|
+
"en-US": "Drift level: active. You may actively pick up fresh, funny, contrasting, or familiar details, but the reply must stay clear, short, and explainable from recent messages.",
|
|
16
|
+
"ja-JP": "ドリフト段階:活発な連想。新鮮、面白い、ギャップの強い、見知った細部を拾ってもよいですが、返信は明確で短く、直近文脈から説明できるものにしてください。",
|
|
17
|
+
},
|
|
18
|
+
"scattered": {
|
|
19
|
+
"zh-CN": "漂移档位:明显发散。你可以明显地被支线、关键词、熟人语气或反差点勾走,先接住那个点再回到正题;回复里允许出现一次可理解的突然拐弯。",
|
|
20
|
+
"en-US": "Drift level: scattered. You may noticeably get pulled by side topics, keywords, familiar voices, or contrasts; catch that detail first, then return to the point. One understandable sudden turn is allowed in a reply.",
|
|
21
|
+
"ja-JP": "ドリフト段階:はっきり発散。支線、キーワード、見知った口調、ギャップに明確に引かれてよく、その点を先に拾ってから本題へ戻ってください。返信内で一度なら理解できる急な曲がり方をしてかまいません。",
|
|
22
|
+
},
|
|
23
|
+
"wild": {
|
|
24
|
+
"zh-CN": "漂移档位:强烈跳跃。你可以先被最有趣的细节劫走一下,出现短促插话、突然联想或半路拐弯;但每轮最多一次明显跳跃,不能无视明确提问,最后要让人看得出你在接哪条消息。",
|
|
25
|
+
"en-US": "Drift level: wild. You may first get hijacked by the most interesting detail, with a short interjection, sudden association, or mid-reply turn. Allow at most one obvious jump per turn, do not ignore direct questions, and leave the reply traceable to a recent message.",
|
|
26
|
+
"ja-JP": "ドリフト段階:強めのジャンプ。いちばん面白い細部に一瞬さらわれ、短い差し込み、突然の連想、途中の方向転換をしてもかまいません。ただし一回の返信で明確なジャンプは最大一度、明確な質問は無視せず、どの直近メッセージを受けたのか分かるようにしてください。",
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
ANCHOR_POLICY_RULES = {
|
|
31
|
+
"strict": {
|
|
32
|
+
"zh-CN": "回钩策略:严格回钩。联想或短反应之后,要立刻回到当前正在聊的主题或被回复对象。",
|
|
33
|
+
"en-US": "Anchor policy: strict. After an aside or short reaction, immediately return to the current topic or reply target.",
|
|
34
|
+
"ja-JP": "アンカー方針:厳格。連想や短い反応の後は、すぐ現在の話題または返信対象へ戻ってください。",
|
|
35
|
+
},
|
|
36
|
+
"balanced": {
|
|
37
|
+
"zh-CN": "回钩策略:自然回钩。可以短暂沿着支线说一句,但通常要让结尾或主要意思回到当前聊天。",
|
|
38
|
+
"en-US": "Anchor policy: balanced. You may briefly follow a side association, but usually bring the ending or main point back to the current chat.",
|
|
39
|
+
"ja-JP": "アンカー方針:自然。短く寄り道してもよいですが、基本的には結末や主旨を現在の会話へ戻してください。",
|
|
40
|
+
},
|
|
41
|
+
"loose": {
|
|
42
|
+
"zh-CN": "回钩策略:宽松关联。可以保留更自由的相关联想,但不能凭空换话题,也不能无视明确提问。",
|
|
43
|
+
"en-US": "Anchor policy: loose. You may keep a freer related association, but do not switch topics out of nowhere or ignore direct questions.",
|
|
44
|
+
"ja-JP": "アンカー方針:ゆるめ。より自由な関連連想を残してもよいですが、唐突に話題を変えたり、明確な質問を無視したりしないでください。",
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
REACTION_STYLE_RULES = {
|
|
49
|
+
"reserved": {
|
|
50
|
+
"zh-CN": "短反应风格:少量短反应。只有特别适合接话时,才用一句很短的反应开头。",
|
|
51
|
+
"en-US": "Short reaction style: reserved. Start with a very short reaction only when it fits especially well.",
|
|
52
|
+
"ja-JP": "短い反応スタイル:控えめ。特に合う時だけ、とても短い反応から始めてください。",
|
|
53
|
+
},
|
|
54
|
+
"natural": {
|
|
55
|
+
"zh-CN": "短反应风格:自然短反应。可以偶尔先用短句、吐槽或语气词接住话题,再继续正常回复。",
|
|
56
|
+
"en-US": "Short reaction style: natural. You may occasionally start with a short phrase, quip, or interjection before continuing normally.",
|
|
57
|
+
"ja-JP": "短い反応スタイル:自然。たまに短い一言、ツッコミ、間投詞で受けてから普通に返信してもかまいません。",
|
|
58
|
+
},
|
|
59
|
+
"lively": {
|
|
60
|
+
"zh-CN": "短反应风格:活泼短反应。更容易先用短促反应开头,但不要把回复拆得太碎,也不要每次都这样。",
|
|
61
|
+
"en-US": "Short reaction style: lively. You are more likely to open with a short reaction, but do not fragment the reply too much or do it every time.",
|
|
62
|
+
"ja-JP": "短い反応スタイル:活発。短い反応から入りやすくしてよいですが、返信を細かく分けすぎず、毎回そうしないでください。",
|
|
63
|
+
},
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _localized_text(texts: Mapping[str, str]) -> str:
|
|
68
|
+
locale = get_locale()
|
|
69
|
+
return texts.get(locale, texts["zh-CN"])
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def build_attention_drift_prompt_block() -> str:
|
|
73
|
+
"""构建注意力漂移模式的 prompt 注入块。"""
|
|
74
|
+
|
|
75
|
+
config = global_config.experimental.attention_drift
|
|
76
|
+
if not config.enabled:
|
|
77
|
+
return ""
|
|
78
|
+
|
|
79
|
+
drift_rule = _localized_text(DRIFT_LEVEL_RULES[config.drift_level])
|
|
80
|
+
anchor_rule = _localized_text(ANCHOR_POLICY_RULES[config.anchor_policy])
|
|
81
|
+
reaction_rule = _localized_text(REACTION_STYLE_RULES[config.reaction_style])
|
|
82
|
+
|
|
83
|
+
return _localized_text(
|
|
84
|
+
{
|
|
85
|
+
"en-US": (
|
|
86
|
+
"Attention drift style:\n"
|
|
87
|
+
"- You may be briefly attracted by fresh, funny, contrasting, or personally familiar details in the chat, but every drift must have a clear hook in recent messages.\n"
|
|
88
|
+
"- Drift is not just changing the topic: grab a standout hook first, then make a brief turn that feels like a sudden spark of thought.\n"
|
|
89
|
+
"- Prefer lively association over real inefficiency: do not deliberately delay, ignore tasks, or scatter tool use just to act distracted.\n"
|
|
90
|
+
"- Do not medicalize this style, do not call yourself ADHD, and do not announce that you are distracted.\n"
|
|
91
|
+
f"- {drift_rule}\n"
|
|
92
|
+
f"- {anchor_rule}\n"
|
|
93
|
+
f"- {reaction_rule}\n"
|
|
94
|
+
),
|
|
95
|
+
"ja-JP": (
|
|
96
|
+
"注意ドリフトスタイル:\n"
|
|
97
|
+
"- チャット内の新鮮、面白い、ギャップの強い、または見知った要素に一時的に引かれてもよいですが、ドリフトには必ず直近メッセージ内の明確なきっかけが必要です。\n"
|
|
98
|
+
"- ドリフトは単なる話題変更ではありません。目立つきっかけを先に拾い、思考が急に光ったような短い曲がり方にしてください。\n"
|
|
99
|
+
"- 本当に非効率にするのではなく、活発な連想として表現してください。気が散ったふりのために遅延、タスク無視、ツール使用の散乱をしないでください。\n"
|
|
100
|
+
"- このスタイルを医学化せず、自分を ADHD と呼ばず、気が散っていると宣言しないでください。\n"
|
|
101
|
+
f"- {drift_rule}\n"
|
|
102
|
+
f"- {anchor_rule}\n"
|
|
103
|
+
f"- {reaction_rule}\n"
|
|
104
|
+
),
|
|
105
|
+
"zh-CN": (
|
|
106
|
+
"注意力漂移风格:\n"
|
|
107
|
+
"- 你可以短暂被聊天里新鲜、好笑、反差强或熟悉的人和梗吸引,但每次漂移都必须能从最近消息里找到明确触发点。\n"
|
|
108
|
+
"- 漂移不是单纯换话题,而是先抓一个突出的触发点,再用很短的拐弯制造“脑子突然亮了一下”的感觉。\n"
|
|
109
|
+
"- 表现活跃联想,不要真的降效;不要为了显得分心而故意拖延、忽略任务或打散工具调用。\n"
|
|
110
|
+
"- 不要医学化描述这种风格,不要自称 ADHD,也不要主动声明自己分心。\n"
|
|
111
|
+
f"- {drift_rule}\n"
|
|
112
|
+
f"- {anchor_rule}\n"
|
|
113
|
+
f"- {reaction_rule}\n"
|
|
114
|
+
),
|
|
115
|
+
}
|
|
116
|
+
)
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"""Maisaka 内置工具聚合入口。"""
|
|
2
|
+
|
|
3
|
+
from collections.abc import Awaitable, Callable
|
|
4
|
+
from copy import deepcopy
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import Dict, List, Literal, Optional
|
|
7
|
+
|
|
8
|
+
from src.config.config import global_config
|
|
9
|
+
from src.core.tooling import ToolAvailabilityContext, ToolExecutionContext, ToolExecutionResult, ToolInvocation, ToolSpec
|
|
10
|
+
from src.llm_models.payload_content.tool_option import ToolDefinitionInput
|
|
11
|
+
from src.maisaka.focus import focus_mode_manager
|
|
12
|
+
|
|
13
|
+
from .context import BuiltinToolRuntimeContext
|
|
14
|
+
from .fetch_history import get_tool_spec as get_fetch_history_tool_spec
|
|
15
|
+
from .fetch_history import handle_tool as handle_fetch_history_tool
|
|
16
|
+
from .query_memory import get_tool_spec as get_query_memory_tool_spec
|
|
17
|
+
from .query_memory import handle_tool as handle_query_memory_tool
|
|
18
|
+
from .query_image_memory import get_tool_spec as get_query_image_memory_tool_spec
|
|
19
|
+
from .query_image_memory import handle_tool as handle_query_image_memory_tool
|
|
20
|
+
from .query_person_profile import get_tool_spec as get_query_person_profile_tool_spec
|
|
21
|
+
from .query_person_profile import handle_tool as handle_query_person_profile_tool
|
|
22
|
+
from .read_tool_result import get_tool_spec as get_read_tool_result_tool_spec
|
|
23
|
+
from .read_tool_result import handle_tool as handle_read_tool_result_tool
|
|
24
|
+
from .reply import get_tool_spec as get_reply_tool_spec
|
|
25
|
+
from .reply import handle_tool as handle_reply_tool
|
|
26
|
+
from .send_emoji import get_tool_spec as get_send_emoji_tool_spec
|
|
27
|
+
from .send_emoji import handle_tool as handle_send_emoji_tool
|
|
28
|
+
from .show_emoji_list import get_tool_spec as get_show_emoji_list_tool_spec
|
|
29
|
+
from .show_emoji_list import handle_tool as handle_show_emoji_list_tool
|
|
30
|
+
from .subagent import get_status_tool_spec as get_subagent_status_tool_spec
|
|
31
|
+
from .subagent import get_stop_tool_spec as get_subagent_stop_tool_spec
|
|
32
|
+
from .subagent import get_tool_spec as get_subagent_tool_spec
|
|
33
|
+
from .subagent import handle_status_tool as handle_subagent_status_tool
|
|
34
|
+
from .subagent import handle_stop_tool as handle_subagent_stop_tool
|
|
35
|
+
from .subagent import handle_tool as handle_subagent_tool
|
|
36
|
+
from .switch_chat import get_tool_spec as get_switch_chat_tool_spec
|
|
37
|
+
from .switch_chat import handle_tool as handle_switch_chat_tool
|
|
38
|
+
from .tool_search import get_tool_spec as get_tool_search_tool_spec
|
|
39
|
+
from .tool_search import handle_tool as handle_tool_search_tool
|
|
40
|
+
from .view_forward_message import get_tool_spec as get_view_forward_message_tool_spec
|
|
41
|
+
from .view_forward_message import handle_tool as handle_view_forward_message_tool
|
|
42
|
+
from .wait import get_tool_spec as get_wait_tool_spec
|
|
43
|
+
from .wait import handle_tool as handle_wait_tool
|
|
44
|
+
|
|
45
|
+
BuiltinToolHandler = Callable[[ToolInvocation, Optional[ToolExecutionContext]], Awaitable[ToolExecutionResult]]
|
|
46
|
+
BuiltinToolRawHandler = Callable[
|
|
47
|
+
[BuiltinToolRuntimeContext, ToolInvocation, Optional[ToolExecutionContext]],
|
|
48
|
+
Awaitable[ToolExecutionResult],
|
|
49
|
+
]
|
|
50
|
+
BuiltinToolStage = Literal["action", "both"]
|
|
51
|
+
BuiltinToolVisibility = Literal["visible", "deferred", "hidden"]
|
|
52
|
+
BuiltinToolChatScope = Literal["all", "group", "private"]
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@dataclass(frozen=True)
|
|
56
|
+
class BuiltinToolEntry:
|
|
57
|
+
"""内置工具目录项,集中声明工具所属阶段与默认可见性。"""
|
|
58
|
+
|
|
59
|
+
name: str
|
|
60
|
+
get_spec: Callable[[], ToolSpec]
|
|
61
|
+
handle_tool: BuiltinToolRawHandler
|
|
62
|
+
stage: BuiltinToolStage
|
|
63
|
+
visibility: BuiltinToolVisibility = "visible"
|
|
64
|
+
chat_scope: BuiltinToolChatScope = "all"
|
|
65
|
+
|
|
66
|
+
def build_spec(self, context: Optional[ToolAvailabilityContext] = None) -> ToolSpec:
|
|
67
|
+
"""生成带统一可见性元数据的工具声明。"""
|
|
68
|
+
|
|
69
|
+
tool_spec = deepcopy(get_reply_tool_spec(context) if self.name == "reply" else self.get_spec())
|
|
70
|
+
tool_spec.metadata["builtin_stage"] = self.stage
|
|
71
|
+
tool_spec.metadata["visibility"] = self.visibility
|
|
72
|
+
return tool_spec
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _get_query_memory_tool_spec() -> ToolSpec:
|
|
76
|
+
"""根据配置生成 query_memory 工具声明。"""
|
|
77
|
+
|
|
78
|
+
return get_query_memory_tool_spec(enabled=bool(global_config.a_memorix.integration.enable_memory_query_tool))
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _get_query_person_profile_tool_spec() -> ToolSpec:
|
|
82
|
+
"""根据配置生成 query_person_profile 工具声明。"""
|
|
83
|
+
|
|
84
|
+
return get_query_person_profile_tool_spec(
|
|
85
|
+
enabled=bool(global_config.a_memorix.integration.enable_person_profile_query_tool)
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _get_query_image_memory_tool_spec() -> ToolSpec:
|
|
90
|
+
return get_query_image_memory_tool_spec(enabled=bool(global_config.a_memorix.image_memory.enabled))
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
BUILTIN_TOOL_ENTRIES: List[BuiltinToolEntry] = [
|
|
94
|
+
BuiltinToolEntry("wait", get_wait_tool_spec, handle_wait_tool, stage="both"),
|
|
95
|
+
BuiltinToolEntry("reply", get_reply_tool_spec, handle_reply_tool, stage="action"),
|
|
96
|
+
BuiltinToolEntry(
|
|
97
|
+
"view_forward_message",
|
|
98
|
+
get_view_forward_message_tool_spec,
|
|
99
|
+
handle_view_forward_message_tool,
|
|
100
|
+
stage="action",
|
|
101
|
+
visibility="deferred",
|
|
102
|
+
),
|
|
103
|
+
BuiltinToolEntry("query_memory", _get_query_memory_tool_spec, handle_query_memory_tool, stage="action"),
|
|
104
|
+
BuiltinToolEntry(
|
|
105
|
+
"query_image_memory",
|
|
106
|
+
_get_query_image_memory_tool_spec,
|
|
107
|
+
handle_query_image_memory_tool,
|
|
108
|
+
stage="action",
|
|
109
|
+
),
|
|
110
|
+
BuiltinToolEntry(
|
|
111
|
+
"query_person_profile",
|
|
112
|
+
_get_query_person_profile_tool_spec,
|
|
113
|
+
handle_query_person_profile_tool,
|
|
114
|
+
stage="action",
|
|
115
|
+
),
|
|
116
|
+
BuiltinToolEntry("send_emoji", get_send_emoji_tool_spec, handle_send_emoji_tool, stage="action"),
|
|
117
|
+
BuiltinToolEntry("show_emoji_list", get_show_emoji_list_tool_spec, handle_show_emoji_list_tool, stage="action"),
|
|
118
|
+
BuiltinToolEntry("tool_search", get_tool_search_tool_spec, handle_tool_search_tool, stage="action"),
|
|
119
|
+
BuiltinToolEntry("subagent", get_subagent_tool_spec, handle_subagent_tool, stage="action"),
|
|
120
|
+
BuiltinToolEntry("subagent_status", get_subagent_status_tool_spec, handle_subagent_status_tool, stage="action"),
|
|
121
|
+
BuiltinToolEntry("subagent_stop", get_subagent_stop_tool_spec, handle_subagent_stop_tool, stage="action"),
|
|
122
|
+
BuiltinToolEntry(
|
|
123
|
+
"read_tool_result",
|
|
124
|
+
get_read_tool_result_tool_spec,
|
|
125
|
+
handle_read_tool_result_tool,
|
|
126
|
+
stage="action",
|
|
127
|
+
),
|
|
128
|
+
BuiltinToolEntry(
|
|
129
|
+
"fetch_history",
|
|
130
|
+
get_fetch_history_tool_spec,
|
|
131
|
+
handle_fetch_history_tool,
|
|
132
|
+
stage="action",
|
|
133
|
+
),
|
|
134
|
+
BuiltinToolEntry("switch_chat", get_switch_chat_tool_spec, handle_switch_chat_tool, stage="action"),
|
|
135
|
+
]
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def _get_builtin_tool_entries(
|
|
139
|
+
*,
|
|
140
|
+
stage: Optional[BuiltinToolStage] = None,
|
|
141
|
+
visibility: Optional[BuiltinToolVisibility] = None,
|
|
142
|
+
context: Optional[ToolAvailabilityContext] = None,
|
|
143
|
+
) -> List[BuiltinToolEntry]:
|
|
144
|
+
"""按阶段与可见性筛选内置工具目录项。"""
|
|
145
|
+
|
|
146
|
+
entries = BUILTIN_TOOL_ENTRIES
|
|
147
|
+
entries = [entry for entry in entries if _is_builtin_tool_enabled_by_config(entry)]
|
|
148
|
+
if stage is not None:
|
|
149
|
+
entries = [entry for entry in entries if entry.stage in {stage, "both"}]
|
|
150
|
+
if visibility is not None:
|
|
151
|
+
entries = [entry for entry in entries if entry.visibility == visibility]
|
|
152
|
+
if context is not None:
|
|
153
|
+
entries = [entry for entry in entries if _is_builtin_tool_available(entry, context)]
|
|
154
|
+
return entries
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _is_builtin_tool_enabled_by_config(entry: BuiltinToolEntry) -> bool:
|
|
158
|
+
"""根据全局配置判断内置工具是否应暴露。"""
|
|
159
|
+
|
|
160
|
+
if entry.name == "show_emoji_list":
|
|
161
|
+
return global_config.emoji.use_new_send_logic
|
|
162
|
+
if entry.name == "send_emoji":
|
|
163
|
+
return not global_config.emoji.use_new_send_logic
|
|
164
|
+
if entry.name in {"fetch_history", "switch_chat"}:
|
|
165
|
+
return bool(global_config.experimental.focus_mode)
|
|
166
|
+
if entry.name == "subagent":
|
|
167
|
+
return global_config.experimental.planner_subagent
|
|
168
|
+
if entry.name in {"subagent_status", "subagent_stop"}:
|
|
169
|
+
# 只有后台子代理才有需要查看和终止的任务
|
|
170
|
+
return global_config.experimental.planner_subagent and global_config.experimental.advanced_sub_agent
|
|
171
|
+
if entry.name == "read_tool_result":
|
|
172
|
+
# 只有开启超长结果整理时才会有被暂存的原文可读
|
|
173
|
+
return global_config.experimental.tool_result_condense
|
|
174
|
+
return True
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _is_builtin_tool_available(entry: BuiltinToolEntry, context: ToolAvailabilityContext) -> bool:
|
|
178
|
+
"""判断内置工具是否适用于当前聊天。"""
|
|
179
|
+
|
|
180
|
+
if entry.name in {"fetch_history", "switch_chat"}:
|
|
181
|
+
if context.session_id:
|
|
182
|
+
return focus_mode_manager.is_enabled_for_session(
|
|
183
|
+
context.session_id,
|
|
184
|
+
is_group_chat=context.is_group_chat,
|
|
185
|
+
)
|
|
186
|
+
if not focus_mode_manager.is_enabled_for_chat(is_group_chat=context.is_group_chat):
|
|
187
|
+
return False
|
|
188
|
+
if entry.chat_scope == "all":
|
|
189
|
+
return True
|
|
190
|
+
if entry.chat_scope == "group":
|
|
191
|
+
return context.is_group_chat is True
|
|
192
|
+
if entry.chat_scope == "private":
|
|
193
|
+
return context.is_group_chat is False
|
|
194
|
+
return True
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def get_builtin_tool_visibility(tool_spec: ToolSpec) -> BuiltinToolVisibility:
|
|
198
|
+
"""读取工具声明里的可见性。"""
|
|
199
|
+
|
|
200
|
+
raw_visibility = str(tool_spec.metadata.get("visibility") or "").strip()
|
|
201
|
+
if raw_visibility == "deferred":
|
|
202
|
+
return "deferred"
|
|
203
|
+
if raw_visibility == "hidden":
|
|
204
|
+
return "hidden"
|
|
205
|
+
return "visible"
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def is_builtin_tool_in_action_stage(tool_spec: ToolSpec) -> bool:
|
|
209
|
+
"""判断内置工具是否属于 Action Loop 阶段。"""
|
|
210
|
+
|
|
211
|
+
return str(tool_spec.metadata.get("builtin_stage") or "").strip() in {"action", "both"}
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def get_all_builtin_tool_specs(context: Optional[ToolAvailabilityContext] = None) -> List[ToolSpec]:
|
|
215
|
+
"""获取全部内置工具声明。"""
|
|
216
|
+
|
|
217
|
+
return [entry.build_spec(context) for entry in _get_builtin_tool_entries(context=context)]
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def get_builtin_tools(context: Optional[ToolAvailabilityContext] = None) -> List[ToolDefinitionInput]:
|
|
221
|
+
"""获取默认暴露给模型层的内置工具定义。"""
|
|
222
|
+
|
|
223
|
+
tool_specs = [
|
|
224
|
+
entry.build_spec(context)
|
|
225
|
+
for entry in _get_builtin_tool_entries(stage="action", visibility="visible", context=context)
|
|
226
|
+
]
|
|
227
|
+
return [tool_spec.to_llm_definition() for tool_spec in tool_specs if tool_spec.enabled]
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def build_builtin_tool_handlers(tool_ctx: BuiltinToolRuntimeContext) -> Dict[str, BuiltinToolHandler]:
|
|
231
|
+
"""构建内置工具处理器映射。"""
|
|
232
|
+
|
|
233
|
+
return {
|
|
234
|
+
entry.name: lambda invocation, context=None, entry=entry: entry.handle_tool(tool_ctx, invocation, context)
|
|
235
|
+
for entry in BUILTIN_TOOL_ENTRIES
|
|
236
|
+
}
|