906 lines
93 KiB
Python
906 lines
93 KiB
Python
"""
|
|
Models - Core data structures for MMA orchestration and project configuration.
|
|
|
|
This module defines the primary dataclasses used throughout the Manual Slop
|
|
application for representing tasks, tracks, and execution context.
|
|
|
|
Key Data Structures:
|
|
- Ticket: Atomic unit of work with status, dependencies, and context requirements
|
|
- Track: Collection of tickets with a shared goal
|
|
- WorkerContext: Execution context for a Tier 3 worker
|
|
- Metadata: Track metadata (id, name, status, timestamps)
|
|
- TrackState: Serializable track state with discussion history
|
|
- FileItem: File configuration with auto-aggregate and force-full flags
|
|
|
|
Status Machine (Ticket):
|
|
todo -> in_progress -> completed
|
|
| |
|
|
v v
|
|
blocked blocked
|
|
|
|
Serialization:
|
|
All dataclasses provide to_dict() and from_dict() class methods for TOML/JSON
|
|
persistence via project_manager.py.
|
|
|
|
Thread Safety:
|
|
These dataclasses are NOT thread-safe. Callers must synchronize mutations
|
|
if sharing instances across threads (e.g., during ConductorEngine execution).
|
|
|
|
Configuration Integration:
|
|
- load_config() / save_config() read/write the global config.toml
|
|
- AGENT_TOOL_NAMES defines the canonical list of MCP tools available to agents
|
|
|
|
See Also:
|
|
- docs/guide_mma.md for MMA orchestration documentation
|
|
- src/dag_engine.py for TrackDAG and ExecutionEngine
|
|
- src/multi_agent_conductor.py for ConductorEngine
|
|
- src/project_manager.py for persistence layer
|
|
"""
|
|
from __future__ import annotations
|
|
import json
|
|
import os
|
|
import tomllib
|
|
import datetime
|
|
from dataclasses import dataclass, field
|
|
from typing import List, Optional, Dict, Any, Union
|
|
from pathlib import Path
|
|
from src.paths import get_config_path
|
|
|
|
PROVIDERS: List[str] = ["gemini", "anthropic", "gemini_cli", "deepseek", "minimax"]
|
|
|
|
CONFIG_PATH = get_config_path()
|
|
|
|
def _clean_nones(data: Any) -> Any:
|
|
if isinstance(data, dict):
|
|
return {k: _clean_nones(v) for k, v in data.items() if v is not None}
|
|
elif isinstance(data, list):
|
|
return [_clean_nones(v) for v in data if v is not None]
|
|
return data
|
|
|
|
def load_config() -> dict[str, Any]:
|
|
"""
|
|
[C: src/multi_agent_conductor.py:ConductorEngine.__init__]
|
|
"""
|
|
with open(CONFIG_PATH, "rb") as f:
|
|
return tomllib.load(f)
|
|
|
|
def save_config(config: dict[str, Any]) -> None:
|
|
import tomli_w
|
|
import sys
|
|
config = _clean_nones(config)
|
|
sys.stderr.write(f"[DEBUG] Saving config. Theme: {config.get('theme')}\n")
|
|
sys.stderr.flush()
|
|
with open(CONFIG_PATH, "wb") as f:
|
|
tomli_w.dump(config, f)
|
|
|
|
AGENT_TOOL_NAMES = [
|
|
"run_powershell",
|
|
"read_file",
|
|
"list_directory",
|
|
"search_files",
|
|
"web_search",
|
|
"fetch_url",
|
|
"get_file_summary",
|
|
"py_get_skeleton",
|
|
"py_get_code_outline",
|
|
"py_get_definition",
|
|
"py_get_signature",
|
|
"py_get_class_summary",
|
|
"py_get_var_declaration",
|
|
"py_get_docstring",
|
|
"py_find_usages",
|
|
"py_get_imports",
|
|
"py_check_syntax",
|
|
"py_get_hierarchy",
|
|
"ts_c_get_skeleton",
|
|
"ts_cpp_get_skeleton",
|
|
"ts_c_get_code_outline",
|
|
"ts_cpp_get_code_outline"
|
|
]
|
|
|
|
DEFAULT_TOOL_CATEGORIES: Dict[str, List[str]] = {
|
|
"General": ["read_file", "list_directory", "search_files", "get_tree", "get_file_summary"],
|
|
"Python": [
|
|
"py_get_skeleton",
|
|
"py_get_code_outline",
|
|
"py_get_definition",
|
|
"py_get_signature",
|
|
"py_get_class_summary",
|
|
"py_get_var_declaration",
|
|
"py_get_docstring",
|
|
"py_update_definition",
|
|
"py_set_signature",
|
|
"py_set_var_declaration"
|
|
],
|
|
"Surgical": ["get_file_slice", "set_file_slice", "edit_file"],
|
|
"Web": ["web_search", "fetch_url"],
|
|
"Analysis": ["py_find_usages", "py_get_imports", "py_check_syntax", "py_get_hierarchy"],
|
|
"C/C++": [
|
|
"ts_c_get_skeleton",
|
|
"ts_cpp_get_skeleton",
|
|
"ts_c_get_code_outline",
|
|
"ts_cpp_get_code_outline",
|
|
"ts_c_get_definition",
|
|
"ts_cpp_get_definition",
|
|
"ts_c_get_signature",
|
|
"ts_cpp_get_signature",
|
|
"ts_c_update_definition",
|
|
"ts_cpp_update_definition"
|
|
],
|
|
"Runtime": ["run_powershell", "get_ui_performance"]
|
|
}
|
|
|
|
def parse_history_entries(history_strings: list[str], roles: list[str]) -> list[dict[str, Any]]:
|
|
import re
|
|
from src import thinking_parser
|
|
entries = []
|
|
for raw in history_strings:
|
|
ts = ""
|
|
rest = raw
|
|
if rest.startswith("@"):
|
|
nl = rest.find("\n")
|
|
if nl != -1:
|
|
ts = rest[1:nl]
|
|
rest = rest[nl + 1:]
|
|
known = roles or ["User", "AI", "Vendor API", "System"]
|
|
role_pat = re.compile(r"^(" + "|".join(re.escape(r) for r in known) + r"):", re.IGNORECASE)
|
|
match = role_pat.match(rest)
|
|
role = match.group(1) if match else "User"
|
|
if match:
|
|
content = rest[match.end():].strip()
|
|
else:
|
|
content = rest
|
|
|
|
entry_obj = {"role": role, "content": content, "collapsed": True, "ts": ts}
|
|
if role == "AI" and ("<thinking>" in content or "<thought>" in content or "Thinking:" in content):
|
|
segments, parsed_content = thinking_parser.parse_thinking_trace(content)
|
|
if segments:
|
|
entry_obj["content"] = parsed_content
|
|
entry_obj["thinking_segments"] = [{"content": s.content, "marker": s.marker} for s in segments]
|
|
|
|
entries.append(entry_obj)
|
|
return entries
|
|
|
|
@dataclass
|
|
class ThinkingSegment:
|
|
content: str
|
|
marker: str # 'thinking', 'thought', or 'Thinking:'
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return {"content": self.content, "marker": self.marker}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[str, Any]) -> "ThinkingSegment":
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return cls(content=data["content"], marker=data["marker"])
|
|
|
|
|
|
@dataclass
|
|
class Ticket:
|
|
id: str
|
|
description: str
|
|
target_symbols: List[str] = field(default_factory=list)
|
|
context_requirements: List[str] = field(default_factory=list)
|
|
depends_on: List[str] = field(default_factory=list)
|
|
status: str = "todo"
|
|
assigned_to: str = "unassigned"
|
|
priority: str = "medium"
|
|
target_file: Optional[str] = None
|
|
blocked_reason: Optional[str] = None
|
|
step_mode: bool = False
|
|
retry_count: int = 0
|
|
manual_block: bool = False
|
|
model_override: Optional[str] = None
|
|
persona_id: Optional[str] = None
|
|
|
|
def mark_blocked(self, reason: str) -> None:
|
|
"""
|
|
[C: src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_mma_models.py:test_ticket_mark_blocked]
|
|
"""
|
|
self.status = "blocked"
|
|
self.blocked_reason = reason
|
|
|
|
def mark_manual_block(self, reason: str) -> None:
|
|
"""
|
|
[C: tests/test_manual_block.py:test_clear_manual_block_method, tests/test_manual_block.py:test_mark_manual_block_method]
|
|
"""
|
|
self.status = "blocked"
|
|
self.blocked_reason = f"[MANUAL] {reason}"
|
|
self.manual_block = True
|
|
|
|
def clear_manual_block(self) -> None:
|
|
"""
|
|
[C: tests/test_manual_block.py:test_clear_manual_block_method]
|
|
"""
|
|
if self.manual_block:
|
|
self.status = "todo"
|
|
self.blocked_reason = None
|
|
self.manual_block = False
|
|
|
|
def mark_complete(self) -> None:
|
|
"""
|
|
[C: src/multi_agent_conductor.py:run_worker_lifecycle, tests/test_conductor_engine_v2.py:do_work, tests/test_mma_models.py:test_ticket_mark_complete, tests/test_mma_models.py:test_track_get_executable_tickets_complex]
|
|
"""
|
|
self.status = "completed"
|
|
|
|
def get(self, key: str, default: Any = None) -> Any:
|
|
"""
|
|
[C: simulation/live_walkthrough.py:main, simulation/ping_pong.py:main, simulation/sim_context.py:ContextSimulation.run, simulation/sim_execution.py:ExecutionSimulation.run, simulation/sim_tools.py:ToolsSimulation.run, simulation/user_agent.py:UserSimAgent.generate_response, simulation/workflow_sim.py:WorkflowSimulator.run_discussion_turn_async, simulation/workflow_sim.py:WorkflowSimulator.wait_for_ai_response, src/multi_agent_conductor.py:ConductorEngine.__init__, src/multi_agent_conductor.py:ConductorEngine.kill_worker, src/multi_agent_conductor.py:ConductorEngine.parse_json_tickets, src/multi_agent_conductor.py:ConductorEngine.run, src/multi_agent_conductor.py:clutch_callback, src/multi_agent_conductor.py:confirm_spawn, src/multi_agent_conductor.py:run_worker_lifecycle, src/multi_agent_conductor.py:worker_comms_callback, src/native_orchestrator.py:NativeOrchestrator.execute_ticket, src/orchestrator_pm.py:generate_tracks, src/orchestrator_pm.py:get_track_history_summary, src/orchestrator_pm.py:module, src/paths.py:_get_project_conductor_dir_from_toml, src/paths.py:get_config_path, src/paths.py:get_global_personas_path, src/paths.py:get_global_presets_path, src/paths.py:get_global_tool_presets_path, src/paths.py:get_global_workspace_profiles_path, src/performance_monitor.py:PerformanceMonitor._get_avg, src/performance_monitor.py:PerformanceMonitor.end_component, src/performance_monitor.py:PerformanceMonitor.get_metrics, src/personas.py:PersonaManager.get_persona_scope, src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.delete_preset, src/presets.py:PresetManager.get_preset_scope, src/presets.py:PresetManager.load_all, src/project_manager.py:branch_discussion, src/project_manager.py:entry_to_str, src/project_manager.py:flat_config, src/project_manager.py:get_all_tracks, src/project_manager.py:load_track_history, src/project_manager.py:migrate_from_legacy_config, src/project_manager.py:promote_take, src/rag_engine.py:RAGEngine.get_all_indexed_paths, src/rag_engine.py:RAGEngine.index_file, src/shell_runner.py:_build_subprocess_env, src/shell_runner.py:_load_env_config, src/summarize.py:build_summary_markdown, src/summarize.py:summarise_file, src/summarize.py:summarise_items, src/summary_cache.py:SummaryCache.get_summary, src/synthesis_formatter.py:format_takes_diff, src/theme.py:apply, src/theme.py:get_palette_colours, src/theme.py:get_shader_config, src/theme.py:get_window_frame_config, src/theme.py:load_from_config, src/theme_2.py:load_from_config, src/tool_bias.py:ToolBiasEngine.apply_semantic_nudges, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/conftest.py:live_gui, tests/mock_gemini_cli.py:main, tests/test_ai_settings_layout.py:test_change_provider_via_hook, tests/test_ai_settings_layout.py:test_set_params_via_custom_callback, tests/test_async_tools.py:mocked_async_dispatch, tests/test_auto_switch_sim.py:test_auto_switch_sim, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_allow_decision, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_deny_decision, tests/test_cli_tool_bridge.py:TestCliToolBridge.test_unreachable_hook_server, tests/test_cli_tool_bridge_mapping.py:TestCliToolBridgeMapping.test_mapping_from_api_format, tests/test_conductor_api_hook_integration.py:simulate_conductor_phase_completion, tests/test_conductor_engine_v2.py:mock_open_side_effect, tests/test_conductor_engine_v2.py:mock_send_side_effect, tests/test_external_editor_gui.py:test_button_click_is_received, tests/test_external_editor_gui.py:test_patch_modal_shows_with_configured_editor, tests/test_external_editor_gui.py:test_vscode_launches_with_diff_view, tests/test_gemini_cli_adapter.py:TestGeminiCliAdapter.test_send_captures_usage_metadata, tests/test_gui2_performance.py:test_performance_benchmarking, tests/test_gui_context_presets.py:test_gui_context_preset_save_load, tests/test_gui_events_v2.py:test_sync_event_queue, tests/test_gui_performance_requirements.py:test_idle_performance_requirements, tests/test_gui_phase4.py:test_delete_ticket_logic, tests/test_gui_stress_performance.py:test_comms_volume_stress_performance, tests/test_gui_text_viewer.py:test_text_viewer_state_update, tests/test_gui_updates.py:test_gui_updates_on_event, tests/test_headless_service.py:TestHeadlessAPI.test_endpoint_no_api_key_configured, tests/test_headless_service.py:TestHeadlessAPI.test_get_context_endpoint, tests/test_headless_service.py:TestHeadlessAPI.test_health_endpoint, tests/test_headless_service.py:TestHeadlessAPI.test_list_sessions_endpoint, tests/test_headless_service.py:TestHeadlessAPI.test_pending_actions_endpoint, tests/test_headless_service.py:TestHeadlessAPI.test_status_endpoint_authorized, tests/test_headless_service.py:TestHeadlessAPI.test_status_endpoint_unauthorized, tests/test_live_gui_integration_v2.py:test_api_gui_state_live, tests/test_live_gui_integration_v2.py:test_user_request_error_handling, tests/test_live_gui_integration_v2.py:test_user_request_integration_flow, tests/test_live_workflow.py:test_full_live_workflow, tests/test_live_workflow.py:wait_for_value, tests/test_log_registry.py:TestLogRegistry.test_register_session, tests/test_log_registry.py:TestLogRegistry.test_update_session_metadata, tests/test_mma_agent_focus_phase3.py:test_comms_log_filter_not_applied_for_prior_session, tests/test_mma_agent_focus_phase3.py:test_comms_log_filter_tier3_only, tests/test_mma_agent_focus_phase3.py:test_tool_log_filter_all, tests/test_mma_agent_focus_phase3.py:test_tool_log_filter_excludes_none_tier, tests/test_mma_agent_focus_phase3.py:test_tool_log_filter_tier3_only, tests/test_mma_approval_indicators.py:_make_app, tests/test_mma_concurrent_tracks_sim.py:test_mma_concurrent_tracks_execution, tests/test_mma_concurrent_tracks_stress_sim.py:_poll_mma_workers, tests/test_mma_concurrent_tracks_stress_sim.py:test_mma_concurrent_tracks_stress, tests/test_mma_dashboard_streams.py:_make_app, tests/test_mma_orchestration_gui.py:test_handle_ai_response_with_stream_id, tests/test_mma_step_mode_sim.py:_poll_mma_status, tests/test_mma_step_mode_sim.py:test_mma_step_mode_approval_flow, tests/test_mock_gemini_cli.py:get_message_content, tests/test_patch_modal_gui.py:test_patch_apply_modal_workflow, tests/test_patch_modal_gui.py:test_patch_modal_appears_on_trigger, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_phase6_engine.py:test_worker_streaming_intermediate, tests/test_preset_windows_layout.py:test_api_hook_under_load, tests/test_preset_windows_layout.py:test_preset_windows_opening, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_rag_phase4_final_verify.py:test_phase4_final_verify, tests/test_rag_phase4_stress.py:test_rag_large_codebase_verification_sim, tests/test_saved_presets_sim.py:test_preset_switching, tests/test_selectable_ui.py:test_selectable_label_stability, tests/test_sim_ai_settings.py:side_effect, tests/test_sim_ai_settings.py:test_ai_settings_simulation_run, tests/test_sim_context.py:test_context_simulation_run, tests/test_sim_execution.py:side_effect, tests/test_spawn_interception_v2.py:test_confirm_spawn_pushed_to_queue, tests/test_status_encapsulation.py:test_status_properties, tests/test_sync_events.py:test_sync_event_queue_multiple, tests/test_sync_events.py:test_sync_event_queue_none_payload, tests/test_sync_events.py:test_sync_event_queue_put_get, tests/test_task_dag_popout_sim.py:test_task_dag_popout, tests/test_tier4_interceptor.py:test_ai_client_passes_qa_callback, tests/test_tiered_aggregation.py:test_app_controller_do_generate_uses_persona_strategy, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_token_usage.py:test_token_usage_tracking, tests/test_tool_management_layout.py:test_tool_management_state_updates, tests/test_tool_preset_env.py:test_tool_preset_env_loading, tests/test_tool_preset_env.py:test_tool_preset_env_no_var, tests/test_tool_presets_sim.py:test_tool_preset_switching, tests/test_ui_cache_controls_sim.py:test_ui_cache_controls, tests/test_ui_summary_only_removal.py:test_project_without_summary_only_loads, tests/test_usage_analytics_popout_sim.py:test_usage_analytics_popout, tests/test_visual_orchestration.py:test_mma_epic_lifecycle, tests/test_visual_sim_gui_ux.py:test_gui_track_creation, tests/test_visual_sim_gui_ux.py:test_gui_ux_event_routing, tests/test_visual_sim_mma_v2.py:_drain_approvals, tests/test_visual_sim_mma_v2.py:_mma_active, tests/test_visual_sim_mma_v2.py:_poll, tests/test_visual_sim_mma_v2.py:_tier3_in_streams, tests/test_visual_sim_mma_v2.py:_tier3_usage_nonzero, tests/test_visual_sim_mma_v2.py:_track_loaded, tests/test_visual_sim_mma_v2.py:test_mma_complete_lifecycle]
|
|
"""
|
|
return getattr(self, key, default)
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return {
|
|
"id": self.id,
|
|
"description": self.description,
|
|
"status": self.status,
|
|
"assigned_to": self.assigned_to,
|
|
"priority": self.priority,
|
|
"target_file": self.target_file,
|
|
"target_symbols": self.target_symbols,
|
|
"context_requirements": self.context_requirements,
|
|
"depends_on": self.depends_on,
|
|
"blocked_reason": self.blocked_reason,
|
|
"step_mode": self.step_mode,
|
|
"retry_count": self.retry_count,
|
|
"manual_block": self.manual_block,
|
|
"model_override": self.model_override,
|
|
"persona_id": self.persona_id,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[str, Any]) -> "Ticket":
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return cls(
|
|
id=data["id"],
|
|
description=data.get("description", ""),
|
|
status=data.get("status", "todo"),
|
|
assigned_to=data.get("assigned_to", "unassigned"),
|
|
priority=data.get("priority", "medium"),
|
|
target_file=data.get("target_file"),
|
|
target_symbols=data.get("target_symbols", []),
|
|
context_requirements=data.get("context_requirements", []),
|
|
depends_on=data.get("depends_on", []),
|
|
blocked_reason=data.get("blocked_reason"),
|
|
step_mode=data.get("step_mode", False),
|
|
retry_count=data.get("retry_count", 0),
|
|
manual_block=data.get("manual_block", False),
|
|
model_override=data.get("model_override"),
|
|
persona_id=data.get("persona_id"),
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class Track:
|
|
id: str
|
|
description: str
|
|
tickets: List[Ticket] = field(default_factory=list)
|
|
|
|
def get_executable_tickets(self) -> List[Ticket]:
|
|
"""
|
|
[C: tests/test_mma_models.py:test_track_get_executable_tickets, tests/test_mma_models.py:test_track_get_executable_tickets_complex]
|
|
"""
|
|
from src.dag_engine import TrackDAG
|
|
dag = TrackDAG(self.tickets)
|
|
return dag.get_ready_tasks()
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return {
|
|
"id": self.id,
|
|
"description": self.description,
|
|
"tickets": [t.to_dict() for t in self.tickets],
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[str, Any]) -> "Track":
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return cls(
|
|
id=data["id"],
|
|
description=data.get("description", ""),
|
|
tickets=[Ticket.from_dict(t) for t in data.get("tickets", [])],
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class WorkerContext:
|
|
ticket_id: str
|
|
model_name: str
|
|
messages: List[Dict[str, Any]] = field(default_factory=list)
|
|
tool_preset: Optional[str] = None
|
|
persona_id: Optional[str] = None
|
|
|
|
|
|
@dataclass
|
|
class Metadata:
|
|
id: str
|
|
name: str
|
|
status: Optional[str] = None
|
|
created_at: Optional[datetime.datetime] = None
|
|
updated_at: Optional[datetime.datetime] = None
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return {
|
|
"id": self.id,
|
|
"name": self.name,
|
|
"status": self.status,
|
|
"created_at": self.created_at.isoformat() if self.created_at else None,
|
|
"updated_at": self.updated_at.isoformat() if self.updated_at else None,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[str, Any]) -> "Metadata":
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
created = data.get("created_at")
|
|
updated = data.get("updated_at")
|
|
if isinstance(created, str):
|
|
try:
|
|
created = datetime.datetime.fromisoformat(created)
|
|
except ValueError:
|
|
created = None
|
|
if isinstance(updated, str):
|
|
try:
|
|
updated = datetime.datetime.fromisoformat(updated)
|
|
except ValueError:
|
|
updated = None
|
|
return cls(
|
|
id=data["id"],
|
|
name=data.get("name", ""),
|
|
status=data.get("status"),
|
|
created_at=created,
|
|
updated_at=updated,
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class TextEditorConfig:
|
|
name: str
|
|
path: str
|
|
diff_args: List[str] = field(default_factory=list)
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return {
|
|
"name": self.name,
|
|
"path": self.path,
|
|
"diff_args": self.diff_args,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[str, Any]) -> "TextEditorConfig":
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return cls(
|
|
name=data["name"],
|
|
path=data["path"],
|
|
diff_args=data.get("diff_args", []),
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class ExternalEditorConfig:
|
|
editors: Dict[str, TextEditorConfig] = field(default_factory=dict)
|
|
default_editor: Optional[str] = None
|
|
|
|
def get_default(self) -> Optional[TextEditorConfig]:
|
|
"""
|
|
[C: tests/test_external_editor.py:TestExternalEditorConfig.test_get_default_fallback_to_first, tests/test_external_editor.py:TestExternalEditorConfig.test_get_default_returns_configured, tests/test_external_editor.py:TestExternalEditorConfig.test_get_default_returns_none_when_empty]
|
|
"""
|
|
if self.default_editor and self.default_editor in self.editors:
|
|
return self.editors[self.default_editor]
|
|
if self.editors:
|
|
return next(iter(self.editors.values()))
|
|
return None
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return {
|
|
"editors": {k: v.to_dict() for k, v in self.editors.items()},
|
|
"default_editor": self.default_editor,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[str, Any]) -> "ExternalEditorConfig":
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
editors = {}
|
|
for name, ed_data in data.get("editors", {}).items():
|
|
if isinstance(ed_data, dict):
|
|
editors[name] = TextEditorConfig.from_dict(ed_data)
|
|
elif isinstance(ed_data, str):
|
|
editors[name] = TextEditorConfig(name=name, path=ed_data)
|
|
return cls(
|
|
editors=editors,
|
|
default_editor=data.get("default_editor"),
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class TrackState:
|
|
metadata: Metadata
|
|
discussion: List[str] = field(default_factory=list)
|
|
tasks: List[Ticket] = field(default_factory=list)
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
serialized_discussion = []
|
|
for item in self.discussion:
|
|
if isinstance(item, dict):
|
|
new_item = dict(item)
|
|
if "ts" in new_item and isinstance(new_item["ts"], datetime.datetime):
|
|
new_item["ts"] = new_item["ts"].isoformat()
|
|
serialized_discussion.append(new_item)
|
|
else:
|
|
serialized_discussion.append(item)
|
|
return {
|
|
"metadata": self.metadata.to_dict(),
|
|
"discussion": serialized_discussion,
|
|
"tasks": [t.to_dict() for t in self.tasks],
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[str, Any]) -> "TrackState":
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
discussion = data.get("discussion", [])
|
|
parsed_discussion = []
|
|
for item in discussion:
|
|
if isinstance(item, dict):
|
|
new_item = dict(item)
|
|
ts = new_item.get("ts")
|
|
if isinstance(ts, str):
|
|
try:
|
|
new_item["ts"] = datetime.datetime.fromisoformat(ts)
|
|
except ValueError:
|
|
pass
|
|
parsed_discussion.append(new_item)
|
|
else:
|
|
parsed_discussion.append(item)
|
|
return cls(
|
|
metadata=Metadata.from_dict(data["metadata"]),
|
|
discussion=parsed_discussion,
|
|
tasks=[Ticket.from_dict(t) for t in data.get("tasks", [])],
|
|
)
|
|
|
|
@dataclass
|
|
class FileItem:
|
|
path: str
|
|
auto_aggregate: bool = True
|
|
force_full: bool = False
|
|
ast_signatures: bool = False
|
|
ast_definitions: bool = False
|
|
ast_mask: dict[str, str] = field(default_factory=dict)
|
|
custom_slices: list[dict] = field(default_factory=list)
|
|
injected_at: Optional[float] = None
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return {
|
|
"path": self.path,
|
|
"auto_aggregate": self.auto_aggregate,
|
|
"force_full": self.force_full,
|
|
"ast_signatures": self.ast_signatures,
|
|
"ast_definitions": self.ast_definitions,
|
|
"ast_mask": self.ast_mask,
|
|
"custom_slices": self.custom_slices,
|
|
"injected_at": self.injected_at,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[str, Any]) -> "FileItem":
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return cls(
|
|
path=data["path"],
|
|
auto_aggregate=data.get("auto_aggregate", True),
|
|
force_full=data.get("force_full", False),
|
|
ast_signatures=data.get("ast_signatures", False),
|
|
ast_definitions=data.get("ast_definitions", False),
|
|
ast_mask=data.get("ast_mask", {}),
|
|
custom_slices=data.get("custom_slices", []),
|
|
injected_at=data.get("injected_at"),
|
|
)
|
|
@dataclass
|
|
class Preset:
|
|
name: str
|
|
system_prompt: str
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return {
|
|
"system_prompt": self.system_prompt,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, name: str, data: Dict[str, Any]) -> "Preset":
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return cls(
|
|
name=name,
|
|
system_prompt=data.get("system_prompt", ""),
|
|
)
|
|
|
|
@dataclass
|
|
class Tool:
|
|
name: str
|
|
approval: str = 'auto'
|
|
weight: int = 3
|
|
parameter_bias: Dict[str, str] = field(default_factory=dict)
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return {
|
|
"name": self.name,
|
|
"approval": self.approval,
|
|
"weight": self.weight,
|
|
"parameter_bias": self.parameter_bias,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[str, Any]) -> "Tool":
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return cls(
|
|
name=data["name"],
|
|
approval=data.get("approval", "auto"),
|
|
weight=data.get("weight", 3),
|
|
parameter_bias=data.get("parameter_bias", {}),
|
|
)
|
|
|
|
@dataclass
|
|
class ToolPreset:
|
|
name: str
|
|
categories: Dict[str, List[Union[Tool, Any]]]
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
serialized_categories = {}
|
|
for cat, tools in self.categories.items():
|
|
serialized_categories[cat] = [t.to_dict() if isinstance(t, Tool) else t for t in tools]
|
|
return {
|
|
"categories": serialized_categories,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, name: str, data: Dict[str, Any]) -> "ToolPreset":
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
raw_categories = data.get("categories", {})
|
|
parsed_categories = {}
|
|
for cat, tools in raw_categories.items():
|
|
parsed_categories[cat] = [Tool.from_dict(t) if isinstance(t, dict) else t for t in tools]
|
|
return cls(
|
|
name=name,
|
|
categories=parsed_categories,
|
|
)
|
|
|
|
@dataclass
|
|
class BiasProfile:
|
|
name: str
|
|
tool_weights: Dict[str, int] = field(default_factory=dict)
|
|
category_multipliers: Dict[str, float] = field(default_factory=dict)
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return {
|
|
"name": self.name,
|
|
"tool_weights": self.tool_weights,
|
|
"category_multipliers": self.category_multipliers,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[str, Any]) -> "BiasProfile":
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return cls(
|
|
name=data["name"],
|
|
tool_weights=data.get("tool_weights", {}),
|
|
category_multipliers=data.get("category_multipliers", {}),
|
|
)
|
|
|
|
@dataclass
|
|
class Persona:
|
|
name: str
|
|
preferred_models: List[Dict[str, Any]] = field(default_factory=list)
|
|
system_prompt: str = ''
|
|
tool_preset: Optional[str] = None
|
|
bias_profile: Optional[str] = None
|
|
context_preset: Optional[str] = None
|
|
aggregation_strategy: Optional[str] = None
|
|
|
|
@property
|
|
def provider(self) -> Optional[str]:
|
|
if not self.preferred_models: return None
|
|
return self.preferred_models[0].get("provider")
|
|
|
|
@property
|
|
def model(self) -> Optional[str]:
|
|
if not self.preferred_models: return None
|
|
return self.preferred_models[0].get("model")
|
|
|
|
@property
|
|
def temperature(self) -> Optional[float]:
|
|
if not self.preferred_models: return None
|
|
return self.preferred_models[0].get("temperature")
|
|
|
|
@property
|
|
def top_p(self) -> Optional[float]:
|
|
if not self.preferred_models: return None
|
|
return self.preferred_models[0].get("top_p")
|
|
|
|
@property
|
|
def max_output_tokens(self) -> Optional[int]:
|
|
if not self.preferred_models: return None
|
|
return self.preferred_models[0].get("max_output_tokens")
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
res = {
|
|
"system_prompt": self.system_prompt,
|
|
}
|
|
if self.preferred_models:
|
|
processed = []
|
|
for m in self.preferred_models:
|
|
if isinstance(m, str):
|
|
processed.append({"model": m})
|
|
else:
|
|
processed.append(m)
|
|
res["preferred_models"] = processed
|
|
if self.tool_preset is not None:
|
|
res["tool_preset"] = self.tool_preset
|
|
if self.bias_profile is not None:
|
|
res["bias_profile"] = self.bias_profile
|
|
if self.context_preset is not None:
|
|
res["context_preset"] = self.context_preset
|
|
if self.aggregation_strategy is not None:
|
|
res["aggregation_strategy"] = self.aggregation_strategy
|
|
return res
|
|
|
|
@classmethod
|
|
def from_dict(cls, name: str, data: Dict[str, Any]) -> "Persona":
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
raw_models = data.get("preferred_models", [])
|
|
parsed_models = []
|
|
for m in raw_models:
|
|
if isinstance(m, str):
|
|
parsed_models.append({"model": m})
|
|
else:
|
|
parsed_models.append(m)
|
|
|
|
# Migration logic: merge legacy fields if they exist
|
|
legacy = {}
|
|
for k in ["provider", "model", "temperature", "top_p", "max_output_tokens"]:
|
|
if data.get(k) is not None:
|
|
legacy[k] = data[k]
|
|
|
|
if legacy:
|
|
if not parsed_models:
|
|
parsed_models.append(legacy)
|
|
else:
|
|
# Merge into first item if it's missing these specific legacy fields
|
|
for k, v in legacy.items():
|
|
if k not in parsed_models[0] or parsed_models[0][k] is None:
|
|
parsed_models[0][k] = v
|
|
|
|
return cls(
|
|
name=name,
|
|
preferred_models=parsed_models,
|
|
system_prompt=data.get("system_prompt", ""),
|
|
tool_preset=data.get("tool_preset"),
|
|
bias_profile=data.get("bias_profile"),
|
|
context_preset=data.get("context_preset"),
|
|
aggregation_strategy=data.get("aggregation_strategy"),
|
|
)
|
|
@dataclass
|
|
class MCPServerConfig:
|
|
name: str
|
|
command: Optional[str] = None
|
|
args: List[str] = field(default_factory=list)
|
|
url: Optional[str] = None
|
|
auto_start: bool = False
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
res = {'auto_start': self.auto_start}
|
|
if self.command: res['command'] = self.command
|
|
if self.args: res['args'] = self.args
|
|
if self.url: res['url'] = self.url
|
|
return res
|
|
|
|
@classmethod
|
|
def from_dict(cls, name: str, data: Dict[str, Any]) -> 'MCPServerConfig':
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return cls(
|
|
name=name,
|
|
command=data.get('command'),
|
|
args=data.get('args', []),
|
|
url=data.get('url'),
|
|
auto_start=data.get('auto_start', False),
|
|
)
|
|
|
|
@dataclass
|
|
class MCPConfiguration:
|
|
mcpServers: Dict[str, MCPServerConfig] = field(default_factory=dict)
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return {
|
|
'mcpServers': {name: cfg.to_dict() for name, cfg in self.mcpServers.items()}
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[str, Any]) -> 'MCPConfiguration':
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
raw_servers = data.get('mcpServers', {})
|
|
parsed_servers = {
|
|
name: MCPServerConfig.from_dict(name, cfg)
|
|
for name, cfg in raw_servers.items()
|
|
}
|
|
return cls(mcpServers=parsed_servers)
|
|
|
|
@dataclass
|
|
class VectorStoreConfig:
|
|
provider: str # 'chroma', 'qdrant', 'mock', 'mcp'
|
|
url: Optional[str] = None
|
|
api_key: Optional[str] = None
|
|
collection_name: str = 'manual_slop'
|
|
mcp_server: Optional[str] = None
|
|
mcp_tool: Optional[str] = None
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return {
|
|
"provider": self.provider,
|
|
"url": self.url,
|
|
"api_key": self.api_key,
|
|
"collection_name": self.collection_name,
|
|
"mcp_server": self.mcp_server,
|
|
"mcp_tool": self.mcp_tool,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[str, Any]) -> "VectorStoreConfig":
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return cls(
|
|
provider=data["provider"],
|
|
url=data.get("url"),
|
|
api_key=data.get("api_key"),
|
|
collection_name=data.get("collection_name", "manual_slop"),
|
|
mcp_server=data.get("mcp_server"),
|
|
mcp_tool=data.get("mcp_tool"),
|
|
)
|
|
|
|
@dataclass
|
|
class RAGConfig:
|
|
enabled: bool = False
|
|
vector_store: VectorStoreConfig = field(default_factory=lambda: VectorStoreConfig(provider='mock'))
|
|
embedding_provider: str = 'gemini'
|
|
chunk_size: int = 1000
|
|
chunk_overlap: int = 200
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return {
|
|
"enabled": self.enabled,
|
|
"vector_store": self.vector_store.to_dict(),
|
|
"embedding_provider": self.embedding_provider,
|
|
"chunk_size": self.chunk_size,
|
|
"chunk_overlap": self.chunk_overlap,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[str, Any]) -> "RAGConfig":
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return cls(
|
|
enabled=data.get("enabled", False),
|
|
vector_store=VectorStoreConfig.from_dict(data.get("vector_store", {"provider": "mock"})),
|
|
embedding_provider=data.get("embedding_provider", "gemini"),
|
|
chunk_size=data.get("chunk_size", 1000),
|
|
chunk_overlap=data.get("chunk_overlap", 200),
|
|
)
|
|
|
|
@dataclass
|
|
class WorkspaceProfile:
|
|
name: str
|
|
ini_content: str
|
|
show_windows: Dict[str, bool]
|
|
panel_states: Dict[str, Any]
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
[C: src/personas.py:PersonaManager.save_persona, src/presets.py:PresetManager.save_preset, src/project_manager.py:save_project, src/project_manager.py:save_track_state, src/tool_presets.py:ToolPresetManager.save_bias_profile, src/tool_presets.py:ToolPresetManager.save_preset, src/workspace_manager.py:WorkspaceManager.save_profile, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_event_serialization.py:test_user_request_event_serialization, tests/test_external_editor.py:TestExternalEditorConfig.test_to_dict, tests/test_external_editor.py:TestTextEditorConfig.test_to_dict, tests/test_file_item_model.py:test_file_item_to_dict, tests/test_gui_events_v2.py:test_user_request_event_payload, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_serialization, tests/test_persona_id.py:test_ticket_persona_id_serialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_serialization, tests/test_thinking_gui.py:test_thinking_segment_model_compatibility, tests/test_ticket_queue.py:test_ticket_to_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_to_dict, tests/test_track_state_schema.py:test_track_state_to_dict_with_none, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return {
|
|
"ini_content": self.ini_content,
|
|
"show_windows": self.show_windows,
|
|
"panel_states": self.panel_states,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, name: str, data: Dict[str, Any]) -> "WorkspaceProfile":
|
|
"""
|
|
[C: src/personas.py:PersonaManager.load_all, src/presets.py:PresetManager.load_all, src/project_manager.py:load_project, src/project_manager.py:load_track_state, src/tool_presets.py:ToolPresetManager.load_all_bias_profiles, src/tool_presets.py:ToolPresetManager.load_all_presets, src/workspace_manager.py:WorkspaceManager.load_all_profiles, tests/test_bias_models.py:test_bias_profile_model, tests/test_bias_models.py:test_tool_model, tests/test_bias_models.py:test_tool_preset_extension, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_dict_editors, tests/test_external_editor.py:TestExternalEditorConfig.test_from_dict_with_string_editors, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_with_diff_args, tests/test_external_editor.py:TestTextEditorConfig.test_from_dict_without_diff_args, tests/test_file_item_model.py:test_file_item_from_dict, tests/test_file_item_model.py:test_file_item_from_dict_defaults, tests/test_mcp_config.py:test_mcp_configuration_to_from_dict, tests/test_mcp_config.py:test_mcp_server_config_to_from_dict, tests/test_per_ticket_model.py:test_model_override_default_on_deserialize, tests/test_per_ticket_model.py:test_model_override_deserialization, tests/test_persona_id.py:test_ticket_persona_id_deserialization, tests/test_persona_models.py:test_persona_defaults, tests/test_persona_models.py:test_persona_deserialization, tests/test_project_serialization.py:TestProjectSerialization.test_backward_compatibility_strings, tests/test_ticket_queue.py:test_ticket_from_dict_default_priority, tests/test_ticket_queue.py:test_ticket_from_dict_priority, tests/test_tiered_aggregation.py:test_persona_aggregation_strategy, tests/test_track_state_schema.py:test_track_state_from_dict, tests/test_track_state_schema.py:test_track_state_from_dict_empty_and_missing, tests/test_ui_summary_only_removal.py:test_file_item_serialization_with_flags]
|
|
"""
|
|
return cls(
|
|
name=name,
|
|
ini_content=data.get("ini_content", ""),
|
|
show_windows=data.get("show_windows", {}),
|
|
panel_states=data.get("panel_states", {}),
|
|
)
|
|
|
|
def load_mcp_config(path: str) -> MCPConfiguration:
|
|
"""
|
|
[C: tests/test_mcp_config.py:test_load_mcp_config]
|
|
"""
|
|
if not os.path.exists(path):
|
|
return MCPConfiguration()
|
|
with open(path, 'r', encoding='utf-8') as f:
|
|
try:
|
|
data = json.load(f)
|
|
return MCPConfiguration.from_dict(data)
|
|
except Exception:
|
|
return MCPConfiguration()
|