Files
nc-talk-ai/lib/Controller/TraceController.php
Pascal Kienast 0739d3da6a Initial open-source release of Talk AI
Talk AI is a multi-bot AI assistant manager for Nextcloud Talk:
per-bot prompts and models, agentic tool calling (MCP + built-in
tools), RAG over Nextcloud files, room-document search, vision and
speech-to-text attachments, persistent bot wikis, approval workflows,
rate limiting, and multi-provider LLM support (any OpenAI-compatible
endpoint).

Developed within EDUC - the European Digital UniverCity
(https://educalliance.eu), where it runs as the 'EDUC AI' assistant on
the alliance-wide Nextcloud portal. This public repository is the
upstream point of truth; deployment-specific tools plug in via the
tool-provider extension point (docs/TOOL_PROVIDERS.md).

License: AGPL-3.0-or-later.
2026-07-08 21:13:13 +02:00

121 lines
3.6 KiB
PHP

<?php
declare(strict_types=1);
namespace OCA\EducAI\Controller;
use Exception;
use OCA\EducAI\Service\TraceService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Controller;
use OCP\IRequest;
use Psr\Log\LoggerInterface;
class TraceController extends Controller {
public function __construct(
string $appName,
IRequest $request,
private TraceService $traceService,
private ?string $userId,
private LoggerInterface $logger,
) {
parent::__construct($appName, $request);
}
/**
* @NoAdminRequired
*/
public function index(): DataResponse {
if ($this->userId === null || $this->userId === '') {
return new DataResponse(['error' => 'Not authenticated'], 401);
}
try {
return new DataResponse($this->traceService->listRunsForUser($this->userId, [
'limit' => $this->request->getParam('limit'),
'offset' => $this->request->getParam('offset'),
'botId' => $this->request->getParam('botId') ?? $this->request->getParam('bot_id'),
'botMentionName' => $this->request->getParam('botMentionName') ?? $this->request->getParam('bot_mention_name'),
'status' => $this->request->getParam('status'),
'from' => $this->request->getParam('from'),
'to' => $this->request->getParam('to'),
'q' => $this->request->getParam('q'),
'onlyErrors' => $this->request->getParam('onlyErrors') ?? $this->request->getParam('only_errors'),
'onlyWithTools' => $this->request->getParam('onlyWithTools') ?? $this->request->getParam('only_with_tools'),
]));
} catch (Exception $e) {
$this->logger->error('Failed to list Talk AI traces', [
'user_id' => $this->userId,
'exception' => $e,
]);
return new DataResponse(['error' => 'Failed to load traces'], 500);
}
}
/**
* @NoAdminRequired
*/
public function show(int $id): DataResponse {
if ($this->userId === null || $this->userId === '') {
return new DataResponse(['error' => 'Not authenticated'], 401);
}
try {
return new DataResponse($this->traceService->getRunForUser($id, $this->userId));
} catch (DoesNotExistException $e) {
return new DataResponse(['error' => 'Trace not found'], 404);
} catch (Exception $e) {
$this->logger->error('Failed to load Talk AI trace', [
'trace_id' => $id,
'user_id' => $this->userId,
'exception' => $e,
]);
return new DataResponse(['error' => 'Trace details unavailable'], 500);
}
}
/**
* @NoAdminRequired
*/
public function destroy(int $id): DataResponse {
if ($this->userId === null || $this->userId === '') {
return new DataResponse(['error' => 'Not authenticated'], 401);
}
try {
$this->traceService->deleteRunForUser($id, $this->userId);
return new DataResponse(['success' => true]);
} catch (DoesNotExistException $e) {
return new DataResponse(['error' => 'Trace not found'], 404);
} catch (Exception $e) {
$this->logger->error('Failed to delete Talk AI trace', [
'trace_id' => $id,
'user_id' => $this->userId,
'exception' => $e,
]);
return new DataResponse(['error' => 'Deletion failed'], 500);
}
}
/**
* @NoAdminRequired
*/
public function clearMine(): DataResponse {
if ($this->userId === null || $this->userId === '') {
return new DataResponse(['error' => 'Not authenticated'], 401);
}
try {
$deleted = $this->traceService->deleteAllForUser($this->userId);
return new DataResponse(['success' => true, 'deleted' => $deleted]);
} catch (Exception $e) {
$this->logger->error('Failed to clear Talk AI traces', [
'user_id' => $this->userId,
'exception' => $e,
]);
return new DataResponse(['error' => 'Deletion failed'], 500);
}
}
}