[Capability] Extract shared element name/description resolution (#481)
This commit is contained in:
parent
312c621417
commit
ff0b5fadc8
3 changed files with 61 additions and 36 deletions
|
|
@ -217,7 +217,6 @@ final class Discoverer implements DiscovererInterface
|
|||
private function processMethod(\ReflectionMethod $method, array &$discoveredCount, \ReflectionAttribute $attribute, array &$tools, array &$resources, array &$prompts, array &$resourceTemplates): void
|
||||
{
|
||||
$className = $method->getDeclaringClass()->getName();
|
||||
$classShortName = $method->getDeclaringClass()->getShortName();
|
||||
$methodName = $method->getName();
|
||||
$attributeClassName = $attribute->getName();
|
||||
|
||||
|
|
@ -226,9 +225,8 @@ final class Discoverer implements DiscovererInterface
|
|||
|
||||
switch ($attributeClassName) {
|
||||
case McpTool::class:
|
||||
$docBlock = $this->docBlockParser->parseDocBlock($method->getDocComment() ?? null);
|
||||
$name = $instance->name ?? ('__invoke' === $methodName ? $classShortName : $methodName);
|
||||
$description = $instance->description ?? $this->docBlockParser->getDescription($docBlock) ?? null;
|
||||
$name = ElementMetadataResolver::resolveName($method, $instance->name);
|
||||
$description = ElementMetadataResolver::resolveDescription($method, $instance->description, $this->docBlockParser);
|
||||
$inputSchema = $this->schemaGenerator->generate($method);
|
||||
$outputSchema = $this->schemaGenerator->generateOutputSchema($method);
|
||||
$tool = new Tool(
|
||||
|
|
@ -246,9 +244,8 @@ final class Discoverer implements DiscovererInterface
|
|||
break;
|
||||
|
||||
case McpResource::class:
|
||||
$docBlock = $this->docBlockParser->parseDocBlock($method->getDocComment() ?? null);
|
||||
$name = $instance->name ?? ('__invoke' === $methodName ? $classShortName : $methodName);
|
||||
$description = $instance->description ?? $this->docBlockParser->getDescription($docBlock) ?? null;
|
||||
$name = ElementMetadataResolver::resolveName($method, $instance->name);
|
||||
$description = ElementMetadataResolver::resolveDescription($method, $instance->description, $this->docBlockParser);
|
||||
$resource = new ResourceDefinition(
|
||||
$instance->uri,
|
||||
$name,
|
||||
|
|
@ -267,8 +264,8 @@ final class Discoverer implements DiscovererInterface
|
|||
|
||||
case McpPrompt::class:
|
||||
$docBlock = $this->docBlockParser->parseDocBlock($method->getDocComment() ?? null);
|
||||
$name = $instance->name ?? ('__invoke' === $methodName ? $classShortName : $methodName);
|
||||
$description = $instance->description ?? $this->docBlockParser->getDescription($docBlock) ?? null;
|
||||
$name = ElementMetadataResolver::resolveName($method, $instance->name);
|
||||
$description = ElementMetadataResolver::resolveDescription($method, $instance->description, $this->docBlockParser);
|
||||
$arguments = [];
|
||||
$paramTags = $this->docBlockParser->getParamTags($docBlock);
|
||||
foreach ($method->getParameters() as $param) {
|
||||
|
|
@ -286,9 +283,8 @@ final class Discoverer implements DiscovererInterface
|
|||
break;
|
||||
|
||||
case McpResourceTemplate::class:
|
||||
$docBlock = $this->docBlockParser->parseDocBlock($method->getDocComment() ?? null);
|
||||
$name = $instance->name ?? ('__invoke' === $methodName ? $classShortName : $methodName);
|
||||
$description = $instance->description ?? $this->docBlockParser->getDescription($docBlock) ?? null;
|
||||
$name = ElementMetadataResolver::resolveName($method, $instance->name);
|
||||
$description = ElementMetadataResolver::resolveDescription($method, $instance->description, $this->docBlockParser);
|
||||
$mimeType = $instance->mimeType;
|
||||
$annotations = $instance->annotations;
|
||||
$meta = $instance->meta ?? null;
|
||||
|
|
|
|||
44
src/Capability/Discovery/ElementMetadataResolver.php
Normal file
44
src/Capability/Discovery/ElementMetadataResolver.php
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the official PHP MCP SDK.
|
||||
*
|
||||
* A collaboration between Symfony and the PHP Foundation.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Mcp\Capability\Discovery;
|
||||
|
||||
/**
|
||||
* Derives an element's name and description from its handler method, used by
|
||||
* both attribute discovery and reflection-based manual registration.
|
||||
*
|
||||
* @author Christopher Hertel <mail@christopher-hertel.de>
|
||||
*/
|
||||
final class ElementMetadataResolver
|
||||
{
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicit names win; otherwise invokable classes are named after the class,
|
||||
* regular handlers after the method.
|
||||
*/
|
||||
public static function resolveName(\ReflectionMethod $method, ?string $name): string
|
||||
{
|
||||
$methodName = $method->getName();
|
||||
|
||||
return $name ?? ('__invoke' === $methodName ? $method->getDeclaringClass()->getShortName() : $methodName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicit descriptions win; otherwise the summary of the method's doc block is used.
|
||||
*/
|
||||
public static function resolveDescription(\ReflectionMethod $method, ?string $description, DocBlockParser $docBlockParser): ?string
|
||||
{
|
||||
return $description ?? $docBlockParser->getDescription($docBlockParser->parseDocBlock($method->getDocComment() ?? null));
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ use Mcp\Capability\Completion\EnumCompletionProvider;
|
|||
use Mcp\Capability\Completion\ListCompletionProvider;
|
||||
use Mcp\Capability\Completion\ProviderInterface;
|
||||
use Mcp\Capability\Discovery\DocBlockParser;
|
||||
use Mcp\Capability\Discovery\ElementMetadataResolver;
|
||||
use Mcp\Capability\Discovery\HandlerResolver;
|
||||
use Mcp\Capability\Discovery\SchemaGenerator;
|
||||
use Mcp\Capability\Discovery\SchemaGeneratorInterface;
|
||||
|
|
@ -106,12 +107,8 @@ final class ReflectedElementLoader implements LoaderInterface
|
|||
$name = $data['name'] ?? 'closure_tool_'.spl_object_id($data['handler']);
|
||||
$description = $data['description'] ?? null;
|
||||
} else {
|
||||
$classShortName = $reflection->getDeclaringClass()->getShortName();
|
||||
$methodName = $reflection->getName();
|
||||
$docBlock = $docBlockParser->parseDocBlock($reflection->getDocComment() ?? null);
|
||||
|
||||
$name = $data['name'] ?? ('__invoke' === $methodName ? $classShortName : $methodName);
|
||||
$description = $data['description'] ?? $docBlockParser->getDescription($docBlock) ?? null;
|
||||
$name = ElementMetadataResolver::resolveName($reflection, $data['name'] ?? null);
|
||||
$description = ElementMetadataResolver::resolveDescription($reflection, $data['description'] ?? null, $docBlockParser);
|
||||
}
|
||||
|
||||
$inputSchema = $data['inputSchema'] ?? $schemaGenerator->generate($reflection);
|
||||
|
|
@ -148,12 +145,8 @@ final class ReflectedElementLoader implements LoaderInterface
|
|||
$name = $data['name'] ?? 'closure_resource_'.spl_object_id($data['handler']);
|
||||
$description = $data['description'] ?? null;
|
||||
} else {
|
||||
$classShortName = $reflection->getDeclaringClass()->getShortName();
|
||||
$methodName = $reflection->getName();
|
||||
$docBlock = $docBlockParser->parseDocBlock($reflection->getDocComment() ?? null);
|
||||
|
||||
$name = $data['name'] ?? ('__invoke' === $methodName ? $classShortName : $methodName);
|
||||
$description = $data['description'] ?? $docBlockParser->getDescription($docBlock) ?? null;
|
||||
$name = ElementMetadataResolver::resolveName($reflection, $data['name'] ?? null);
|
||||
$description = ElementMetadataResolver::resolveDescription($reflection, $data['description'] ?? null, $docBlockParser);
|
||||
}
|
||||
|
||||
$resource = new ResourceDefinition(
|
||||
|
|
@ -189,12 +182,8 @@ final class ReflectedElementLoader implements LoaderInterface
|
|||
$name = $data['name'] ?? 'closure_template_'.spl_object_id($data['handler']);
|
||||
$description = $data['description'] ?? null;
|
||||
} else {
|
||||
$classShortName = $reflection->getDeclaringClass()->getShortName();
|
||||
$methodName = $reflection->getName();
|
||||
$docBlock = $docBlockParser->parseDocBlock($reflection->getDocComment() ?? null);
|
||||
|
||||
$name = $data['name'] ?? ('__invoke' === $methodName ? $classShortName : $methodName);
|
||||
$description = $data['description'] ?? $docBlockParser->getDescription($docBlock) ?? null;
|
||||
$name = ElementMetadataResolver::resolveName($reflection, $data['name'] ?? null);
|
||||
$description = ElementMetadataResolver::resolveDescription($reflection, $data['description'] ?? null, $docBlockParser);
|
||||
}
|
||||
|
||||
$template = new ResourceTemplate(
|
||||
|
|
@ -229,12 +218,8 @@ final class ReflectedElementLoader implements LoaderInterface
|
|||
$name = $data['name'] ?? 'closure_prompt_'.spl_object_id($data['handler']);
|
||||
$description = $data['description'] ?? null;
|
||||
} else {
|
||||
$classShortName = $reflection->getDeclaringClass()->getShortName();
|
||||
$methodName = $reflection->getName();
|
||||
$docBlock = $docBlockParser->parseDocBlock($reflection->getDocComment() ?? null);
|
||||
|
||||
$name = $data['name'] ?? ('__invoke' === $methodName ? $classShortName : $methodName);
|
||||
$description = $data['description'] ?? $docBlockParser->getDescription($docBlock) ?? null;
|
||||
$name = ElementMetadataResolver::resolveName($reflection, $data['name'] ?? null);
|
||||
$description = ElementMetadataResolver::resolveDescription($reflection, $data['description'] ?? null, $docBlockParser);
|
||||
}
|
||||
|
||||
$arguments = [];
|
||||
|
|
|
|||
Loading…
Reference in a new issue