* * @author Kyrian Obikwelu */ final class CompletionCompleteHandler implements RequestHandlerInterface { public function __construct( private readonly RegistryInterface $registry, private readonly ?ContainerInterface $container = null, ) { } public function supports(Request $request): bool { return $request instanceof CompletionCompleteRequest; } /** * @return Response|Error */ public function handle(Request $request, SessionInterface $session): Response|Error { \assert($request instanceof CompletionCompleteRequest); $name = $request->argument['name'] ?? ''; $value = $request->argument['value'] ?? ''; try { $providers = match (true) { $request->ref instanceof PromptReference => $this->registry->getPrompt($request->ref->name)->completionProviders, $request->ref instanceof ResourceReference => $this->resourceCompletionProviders($request->ref->uri), }; $provider = $providers[$name] ?? null; if (null === $provider) { return new Response($request->getId(), new CompletionCompleteResult([])); } if (\is_string($provider)) { if (!class_exists($provider)) { return Error::forInternalError('Invalid completion provider', $request->getId()); } $provider = $this->container?->has($provider) ? $this->container->get($provider) : new $provider(); } if (!$provider instanceof ProviderInterface) { return Error::forInternalError('Invalid completion provider type', $request->getId()); } $completions = $provider->getCompletions($value); $total = \count($completions); $hasMore = $total > 100; $paged = \array_slice($completions, 0, 100); return new Response($request->getId(), new CompletionCompleteResult($paged, $total, $hasMore)); } catch (PromptNotFoundException|ResourceNotFoundException $e) { return Error::forResourceNotFound($e->getMessage(), $request->getId()); } catch (\Throwable $e) { return Error::forInternalError('Error while handling completion request', $request->getId()); } } /** * @return array */ private function resourceCompletionProviders(string $uri): array { $reference = $this->registry->getResource($uri); return $reference instanceof ResourceTemplateReference ? $reference->completionProviders : []; } }