$serverClass */ public function __construct( protected Container $app, protected string $serverClass ) { // } /** * @param class-string|Tool $tool * @param array $arguments */ public function tool(Tool|string $tool, array $arguments = []): TestResponse { return $this->run('tools/call', $tool, $arguments); } /** * @param class-string|Prompt $prompt * @param array $arguments */ public function prompt(Prompt|string $prompt, array $arguments = []): TestResponse { return $this->run('prompts/get', $prompt, $arguments); } /** * @param class-string|Resource $resource * @param array $arguments */ public function resource(Resource|string $resource, array $arguments = []): TestResponse { return $this->run('resources/read', $resource, $arguments); } /** * @param class-string|Primitive $primitive * @param array $currentArgs */ public function completion( Primitive|string $primitive, string $argumentName, string $argumentValue = '', array $currentArgs = [] ): TestResponse { $primitive = $this->resolvePrimitive($primitive); $server = $this->initializeServer(); $request = new JsonRpcRequest( uniqid(), 'completion/complete', [ 'ref' => $this->buildCompletionRef($primitive), 'argument' => [ 'name' => $argumentName, 'value' => $argumentValue, ], 'context' => [ 'arguments' => $currentArgs, ], ], ); $response = $this->executeRequest($server, $request); return new TestResponse($primitive, $response); } /** * @return array */ protected function buildCompletionRef(Primitive $primitive): array { return match (true) { $primitive instanceof Prompt => [ 'type' => 'ref/prompt', 'name' => $primitive->name(), ], $primitive instanceof Resource => [ 'type' => 'ref/resource', 'uri' => $primitive->uri(), ], default => throw new InvalidArgumentException('Unsupported primitive type for completion.'), }; } protected function resolvePrimitive(Primitive|string $primitive): Primitive { return is_string($primitive) ? Container::getInstance()->make($primitive) : $primitive; } protected function initializeServer(): Server { $server = Container::getInstance()->make( $this->serverClass, ['transport' => new FakeTransporter] ); $server->start(); return $server; } protected function executeRequest(Server $server, JsonRpcRequest $request): mixed { try { return (fn (): iterable|JsonRpcResponse => $this->runMethodHandle($request, $this->createContext()))->call($server); } catch (JsonRpcException $jsonRpcException) { return $jsonRpcException->toJsonRpcResponse(); } } public function actingAs(Authenticatable $user, ?string $guard = null): static { if (property_exists($user, 'wasRecentlyCreated')) { $user->wasRecentlyCreated = false; } $this->app['auth']->guard($guard)->setUser($user); $this->app['auth']->shouldUse($guard); return $this; } /** * @param class-string|Primitive $primitive * @param array $arguments * * @throws JsonRpcException */ protected function run(string $method, Primitive|string $primitive, array $arguments = []): TestResponse { $primitive = $this->resolvePrimitive($primitive); $server = $this->initializeServer(); $request = new JsonRpcRequest( uniqid(), $method, [ ...$primitive->toMethodCall(), 'arguments' => $arguments, ], ); $response = $this->executeRequest($server, $request); return new TestResponse($primitive, $response); } }