yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
agent_ui_controller.cc
Go to the documentation of this file.
2#include "absl/time/clock.h"
3
4#if defined(YAZE_BUILD_AGENT_UI)
5
15#include "rom/rom.h"
16#include "util/log.h"
17
18namespace yaze {
19namespace editor {
20
21void AgentUiController::Initialize(ToastManager* toast_manager,
22 ProposalDrawer* proposal_drawer,
23 RightPanelManager* right_panel_manager,
24 PanelManager* panel_manager,
25 UserSettings* user_settings) {
26 toast_manager_ = toast_manager;
27 right_panel_manager_ = right_panel_manager;
28 panel_manager_ = panel_manager;
29 user_settings_ = user_settings;
30
31 // Create initial agent session
32 session_manager_.CreateSession("Agent 1");
33
34 // Register OracleRamPanel
35 if (panel_manager) {
36 panel_manager->RegisterEditorPanel(std::make_unique<OracleRamPanel>());
37 }
38
39 // Provide minimal dependencies so panels register with the activity bar
40 if (panel_manager) {
41 EditorDependencies deps;
42 deps.panel_manager = panel_manager;
43 deps.toast_manager = toast_manager;
44 deps.user_settings = user_settings_;
45 agent_editor_.SetDependencies(deps);
46 }
47
48 // Initialize the AgentEditor
49 agent_editor_.Initialize();
50 agent_editor_.InitializeWithDependencies(toast_manager, proposal_drawer,
51 /*rom=*/nullptr);
52 agent_editor_.SetContext(&agent_ui_context_);
53
54 // Wire agent/chat into the right sidebar experience
55 if (right_panel_manager_) {
56 right_panel_manager_->SetAgentChat(agent_editor_.GetAgentChat());
57 right_panel_manager_->SetProposalDrawer(proposal_drawer);
58 right_panel_manager_->SetToastManager(toast_manager);
59 }
60
61 // Initialize knowledge service if available
62#if defined(Z3ED_AI)
63 InitializeKnowledge();
64
65 // Set up knowledge panel callback
66 agent_editor_.SetKnowledgePanelCallback([this, toast_manager]() {
67 AgentKnowledgePanel::Callbacks callbacks;
68 callbacks.set_preference = [this](const std::string& key,
69 const std::string& value) {
70 if (knowledge_initialized_) {
71 learned_knowledge_.SetPreference(key, value);
72 learned_knowledge_.SaveAll();
73 SyncKnowledgeToContext();
74 }
75 };
76 callbacks.remove_preference = [this](const std::string& key) {
77 if (knowledge_initialized_) {
78 learned_knowledge_.RemovePreference(key);
79 learned_knowledge_.SaveAll();
80 SyncKnowledgeToContext();
81 }
82 };
83 callbacks.clear_all_knowledge = [this]() {
84 if (knowledge_initialized_) {
85 learned_knowledge_.ClearAll();
86 SyncKnowledgeToContext();
87 }
88 };
89 callbacks.export_knowledge = [this, toast_manager]() {
90 if (knowledge_initialized_) {
91 auto json_or = learned_knowledge_.ExportToJSON();
92 if (json_or.ok()) {
93 // TODO: Save to file or clipboard
94 if (toast_manager) {
95 toast_manager->Show("Knowledge exported", ToastType::kSuccess);
96 }
97 }
98 }
99 };
100 callbacks.refresh_knowledge = [this]() {
101 SyncKnowledgeToContext();
102 };
103
104 knowledge_panel_.Draw(GetContext(), GetKnowledgeService(), callbacks,
105 toast_manager_);
106 });
107#endif
108
109 // Initial state sync from editor to context
110 SyncStateFromEditor();
111}
112
114 if (!user_settings_) {
115 return;
116 }
117 agent_editor_.ApplyUserSettingsDefaults(force);
118}
119
121 agent_editor_.SetRomContext(rom);
122 agent_ui_context_.SetRom(rom);
123}
124
125void AgentUiController::SetProjectContext(project::YazeProject* project) {
126 agent_ui_context_.SetProject(project);
127
128 // Propagate to active session context
129 if (AgentSession* session = session_manager_.GetActiveSession()) {
130 session->context.SetProject(project);
131 }
132}
133
134void AgentUiController::SetAsarWrapperContext(core::AsarWrapper* asar_wrapper) {
135 agent_ui_context_.SetAsarWrapper(asar_wrapper);
136
137 // Propagate to active session context
138 if (AgentSession* session = session_manager_.GetActiveSession()) {
139 session->context.SetAsarWrapper(asar_wrapper);
140 }
141}
142
143absl::Status AgentUiController::Update() {
144 // Update the AgentEditor (draws its cards via PanelManager)
145 auto status = agent_editor_.Update();
146
147 return status;
148}
149
150void AgentUiController::SyncStateFromEditor() {
151 // Pull config from AgentEditor's current profile
152 const auto& profile = agent_editor_.GetCurrentProfile();
153 auto& ctx_config = agent_ui_context_.agent_config();
154
155 // Check for changes between Editor and Context
156 bool changed = false;
157 if (ctx_config.ai_provider != profile.provider)
158 changed = true;
159 if (ctx_config.ai_model != profile.model)
160 changed = true;
161 if (ctx_config.ollama_host != profile.ollama_host)
162 changed = true;
163 if (ctx_config.gemini_api_key != profile.gemini_api_key)
164 changed = true;
165 if (ctx_config.anthropic_api_key != profile.anthropic_api_key)
166 changed = true;
167 if (ctx_config.openai_api_key != profile.openai_api_key)
168 changed = true;
169 if (ctx_config.openai_base_url != profile.openai_base_url)
170 changed = true;
171 if (ctx_config.host_id != profile.host_id)
172 changed = true;
173 // ... (Simplified sync logic for now)
174
175 if (changed) {
176 ctx_config.ai_provider = profile.provider;
177 ctx_config.ai_model = profile.model;
178 ctx_config.ollama_host = profile.ollama_host;
179 ctx_config.gemini_api_key = profile.gemini_api_key;
180 ctx_config.anthropic_api_key = profile.anthropic_api_key;
181 ctx_config.openai_api_key = profile.openai_api_key;
182 ctx_config.openai_base_url = profile.openai_base_url;
183 ctx_config.host_id = profile.host_id;
184
185 // Update last synced state
186 last_synced_config_ = ctx_config;
187
188 SyncStateToComponents();
189 }
190}
191
192void AgentUiController::SyncStateToComponents() {
193 // Push context state to chat widget if needed
194 // AgentChat uses context directly, so this might be redundant if it holds a pointer
195 if (auto* chat = agent_editor_.GetAgentChat()) {
196 chat->SetContext(&agent_ui_context_);
197 }
198}
199
201 agent_editor_.set_active(true);
202}
203
205 agent_editor_.set_active(true);
206
207 if (panel_manager_) {
208 const size_t session_id = panel_manager_->GetActiveSessionId();
209 panel_manager_->ShowPanel(session_id, "agent.chat");
210 panel_manager_->MarkPanelRecentlyUsed("agent.chat");
211 }
212
213 if (right_panel_manager_) {
214 right_panel_manager_->OpenPanel(RightPanelManager::PanelType::kAgentChat);
215 }
216
217 if (auto* chat = agent_editor_.GetAgentChat()) {
218 chat->set_active(true);
219 chat->ScrollToBottom();
220 }
221}
222
224 return true;
225}
226
228 // No legacy popups
229}
230
232 return &agent_editor_;
233}
234
235AgentUIContext* AgentUiController::GetContext() {
236 // Return active session's context if available
237 if (AgentSession* session = session_manager_.GetActiveSession()) {
238 return &session->context;
239 }
240 // Fall back to legacy context
241 return &agent_ui_context_;
242}
243
244const AgentUIContext* AgentUiController::GetContext() const {
245 // Return active session's context if available
246 if (const AgentSession* session = session_manager_.GetActiveSession()) {
247 return &session->context;
248 }
249 // Fall back to legacy context
250 return &agent_ui_context_;
251}
252
253#if defined(Z3ED_AI)
254cli::agent::LearnedKnowledgeService* AgentUiController::GetKnowledgeService() {
255 if (!knowledge_initialized_) {
256 return nullptr;
257 }
258 return &learned_knowledge_;
259}
260
261bool AgentUiController::IsKnowledgeServiceAvailable() const {
262 return knowledge_initialized_;
263}
264
265void AgentUiController::InitializeKnowledge() {
266 if (knowledge_initialized_) {
267 return;
268 }
269
270 auto status = learned_knowledge_.Initialize();
271 if (status.ok()) {
272 knowledge_initialized_ = true;
273 SyncKnowledgeToContext();
274 LOG_INFO("AgentUiController",
275 "LearnedKnowledgeService initialized successfully");
276 } else {
277 LOG_ERROR("AgentUiController",
278 "Failed to initialize LearnedKnowledgeService: %s",
279 status.message().data());
280 }
281}
282
283void AgentUiController::SyncKnowledgeToContext() {
284 if (!knowledge_initialized_) {
285 return;
286 }
287
288 // Update knowledge state in context with stats from service
289 auto stats = learned_knowledge_.GetStats();
290 auto& knowledge_state = agent_ui_context_.knowledge_state();
291
292 knowledge_state.initialized = true;
293 knowledge_state.preference_count = stats.preference_count;
294 knowledge_state.pattern_count = stats.pattern_count;
295 knowledge_state.project_count = stats.project_count;
296 knowledge_state.memory_count = stats.memory_count;
297 knowledge_state.last_refresh = absl::Now();
298
299 // Also update active session context
300 if (AgentSession* session = session_manager_.GetActiveSession()) {
301 session->context.knowledge_state() = knowledge_state;
302 }
303}
304#endif // defined(Z3ED_AI)
305
306} // namespace editor
307} // namespace yaze
308
309#endif // defined(YAZE_BUILD_AGENT_UI)
void Initialize(ToastManager *toast_manager, ProposalDrawer *proposal_drawer, RightPanelManager *right_panel_manager, PanelManager *panel_manager, UserSettings *user_settings)
void SetProjectContext(project::YazeProject *project)
void ApplyUserSettingsDefaults(bool force=false)
void SetAsarWrapperContext(core::AsarWrapper *asar_wrapper)
#define LOG_ERROR(category, format,...)
Definition log.h:109
#define LOG_INFO(category, format,...)
Definition log.h:105