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 RightDrawerManager* right_drawer_manager,
24 WorkspaceWindowManager* window_manager,
25 UserSettings* user_settings) {
26 toast_manager_ = toast_manager;
27 right_drawer_manager_ = right_drawer_manager;
28 window_manager_ = window_manager;
29 user_settings_ = user_settings;
30
31 // Create initial agent session
32 session_manager_.CreateSession("Agent 1");
33
34 // Register OracleRamPanel
35 if (window_manager) {
36 window_manager->RegisterWindowContent(std::make_unique<OracleRamPanel>());
37 }
38
39 // Provide minimal dependencies so panels register with the activity bar
40 if (window_manager) {
41 EditorDependencies deps;
42 deps.window_manager = window_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_drawer_manager_) {
56 right_drawer_manager_->SetAgentChat(agent_editor_.GetAgentChat());
57 right_drawer_manager_->SetProposalDrawer(proposal_drawer);
58 right_drawer_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
144 const std::map<std::string, core::AsarSymbol>* table) {
145 agent_ui_context_.SetAssemblySymbolTable(table);
146 if (AgentSession* session = session_manager_.GetActiveSession()) {
147 session->context.SetAssemblySymbolTable(table);
148 }
149}
150
151absl::Status AgentUiController::Update() {
152 // Update the AgentEditor (draws its cards via WorkspaceWindowManager)
153 auto status = agent_editor_.Update();
154
155 return status;
156}
157
158void AgentUiController::SyncStateFromEditor() {
159 // Pull config from AgentEditor's current profile
160 const auto& profile = agent_editor_.GetCurrentProfile();
161 auto& ctx_config = agent_ui_context_.agent_config();
162
163 // Check for changes between Editor and Context
164 bool changed = false;
165 if (ctx_config.ai_provider != profile.provider)
166 changed = true;
167 if (ctx_config.ai_model != profile.model)
168 changed = true;
169 if (ctx_config.ollama_host != profile.ollama_host)
170 changed = true;
171 if (ctx_config.gemini_api_key != profile.gemini_api_key)
172 changed = true;
173 if (ctx_config.anthropic_api_key != profile.anthropic_api_key)
174 changed = true;
175 if (ctx_config.openai_api_key != profile.openai_api_key)
176 changed = true;
177 if (ctx_config.openai_base_url != profile.openai_base_url)
178 changed = true;
179 if (ctx_config.host_id != profile.host_id)
180 changed = true;
181 // ... (Simplified sync logic for now)
182
183 if (changed) {
184 ctx_config.ai_provider = profile.provider;
185 ctx_config.ai_model = profile.model;
186 ctx_config.ollama_host = profile.ollama_host;
187 ctx_config.gemini_api_key = profile.gemini_api_key;
188 ctx_config.anthropic_api_key = profile.anthropic_api_key;
189 ctx_config.openai_api_key = profile.openai_api_key;
190 ctx_config.openai_base_url = profile.openai_base_url;
191 ctx_config.host_id = profile.host_id;
192
193 // Update last synced state
194 last_synced_config_ = ctx_config;
195
196 SyncStateToComponents();
197 }
198}
199
200void AgentUiController::SyncStateToComponents() {
201 // Push context state to chat widget if needed
202 // AgentChat uses context directly, so this might be redundant if it holds a pointer
203 if (auto* chat = agent_editor_.GetAgentChat()) {
204 chat->SetContext(&agent_ui_context_);
205 }
206}
207
209 agent_editor_.set_active(true);
210}
211
213 agent_editor_.set_active(true);
214
215 if (window_manager_) {
216 const size_t session_id = window_manager_->GetActiveSessionId();
217 window_manager_->OpenWindow(session_id, "agent.chat");
218 window_manager_->MarkWindowRecentlyUsed("agent.chat");
219 }
220
221 if (right_drawer_manager_) {
222 right_drawer_manager_->OpenDrawer(RightDrawerManager::DrawerType::kAgentChat);
223 }
224
225 if (auto* chat = agent_editor_.GetAgentChat()) {
226 chat->set_active(true);
227 chat->ScrollToBottom();
228 }
229}
230
232 return true;
233}
234
236 // No legacy popups
237}
238
240 return &agent_editor_;
241}
242
243AgentUIContext* AgentUiController::GetContext() {
244 // Return active session's context if available
245 if (AgentSession* session = session_manager_.GetActiveSession()) {
246 return &session->context;
247 }
248 // Fall back to legacy context
249 return &agent_ui_context_;
250}
251
252const AgentUIContext* AgentUiController::GetContext() const {
253 // Return active session's context if available
254 if (const AgentSession* session = session_manager_.GetActiveSession()) {
255 return &session->context;
256 }
257 // Fall back to legacy context
258 return &agent_ui_context_;
259}
260
261#if defined(Z3ED_AI)
262cli::agent::LearnedKnowledgeService* AgentUiController::GetKnowledgeService() {
263 if (!knowledge_initialized_) {
264 return nullptr;
265 }
266 return &learned_knowledge_;
267}
268
269bool AgentUiController::IsKnowledgeServiceAvailable() const {
270 return knowledge_initialized_;
271}
272
273void AgentUiController::InitializeKnowledge() {
274 if (knowledge_initialized_) {
275 return;
276 }
277
278 auto status = learned_knowledge_.Initialize();
279 if (status.ok()) {
280 knowledge_initialized_ = true;
281 SyncKnowledgeToContext();
282 LOG_INFO("AgentUiController",
283 "LearnedKnowledgeService initialized successfully");
284 } else {
285 LOG_ERROR("AgentUiController",
286 "Failed to initialize LearnedKnowledgeService: %s",
287 status.message().data());
288 }
289}
290
291void AgentUiController::SyncKnowledgeToContext() {
292 if (!knowledge_initialized_) {
293 return;
294 }
295
296 // Update knowledge state in context with stats from service
297 auto stats = learned_knowledge_.GetStats();
298 auto& knowledge_state = agent_ui_context_.knowledge_state();
299
300 knowledge_state.initialized = true;
301 knowledge_state.preference_count = stats.preference_count;
302 knowledge_state.pattern_count = stats.pattern_count;
303 knowledge_state.project_count = stats.project_count;
304 knowledge_state.memory_count = stats.memory_count;
305 knowledge_state.last_refresh = absl::Now();
306
307 // Also update active session context
308 if (AgentSession* session = session_manager_.GetActiveSession()) {
309 session->context.knowledge_state() = knowledge_state;
310 }
311}
312#endif // defined(Z3ED_AI)
313
314} // namespace editor
315} // namespace yaze
316
317#endif // defined(YAZE_BUILD_AGENT_UI)
void SetProjectContext(project::YazeProject *project)
void ApplyUserSettingsDefaults(bool force=false)
void SetAssemblySymbolTableContext(const std::map< std::string, core::AsarSymbol > *table)
void Initialize(ToastManager *toast_manager, ProposalDrawer *proposal_drawer, RightDrawerManager *right_drawer_manager, WorkspaceWindowManager *window_manager, UserSettings *user_settings)
void SetAsarWrapperContext(core::AsarWrapper *asar_wrapper)
#define LOG_ERROR(category, format,...)
Definition log.h:109
#define LOG_INFO(category, format,...)
Definition log.h:105