AIProvider::latest()->get(), 'prompts' => AIPrompt::latest()->paginate(15, '*', 'prompts'), 'executions' => AIExecution::latest()->limit(15)->get(), 'sources' => AIKnowledgeSource::latest()->limit(15)->get()]); } public function storeProvider(Request $request): RedirectResponse { $data = $request->validate(['name' => 'required|string|max:100', 'driver' => 'required|in:openai_compatible,openai,lm_studio,ollama', 'base_url' => 'nullable|url', 'api_key' => 'nullable|string', 'default_model' => 'required|string|max:150', 'is_default' => 'nullable|boolean']); if ($request->boolean('is_default')) { AIProvider::query()->update(['is_default' => false]); } $data['is_default'] = $request->boolean('is_default'); AIProvider::create($data); return back()->with('status', 'AI provider created.'); } public function testProvider(AIProvider $provider, AIManager $manager): RedirectResponse { $result = $manager->testProvider($provider->id); return back()->with($result['ok'] ? 'status' : 'error', $result['message']); } public function storePrompt(Request $request): RedirectResponse { $data = $request->validate(['name' => 'required|string|max:120', 'slug' => 'nullable|alpha_dash|max:140', 'purpose' => 'nullable|string|max:100', 'system_prompt' => 'nullable|string', 'user_template' => 'required|string']); $data['slug'] = $data['slug'] ?: Str::slug($data['name']); $data['created_by'] = auth()->id(); AIPrompt::create($data); return back()->with('status', 'Prompt created.'); } public function execute(Request $request, AIPrompt $prompt, AIManager $manager): RedirectResponse { $data = $request->validate(['input' => 'required|string|max:50000', 'provider_id' => 'nullable|exists:ai_providers,id']); $execution = $manager->execute($prompt, ['input' => $data['input']], ['provider_id' => $data['provider_id'] ?? null]); return back()->with($execution->status === 'completed' ? 'status' : 'error', $execution->status === 'completed' ? 'AI execution completed.' : $execution->error); } public function storeSource(Request $request, KnowledgeIndexer $indexer): RedirectResponse { $data = $request->validate(['name' => 'required|string|max:150', 'content' => 'required|string|max:1000000']); $source = AIKnowledgeSource::create(['name' => $data['name'], 'source_kind' => 'manual', 'content' => $data['content'], 'status' => 'pending']); $indexer->index($source); return back()->with('status','Knowledge source indexed.'); } }