feat: add comprehensive framework features and deployment improvements
Major additions: - Storage abstraction layer with filesystem and in-memory implementations - Gitea API integration with MCP tools for repository management - Console dialog mode with interactive command execution - WireGuard VPN DNS fix implementation and documentation - HTTP client streaming response support - Router generic result type - Parameter type validator for framework core Framework enhancements: - Console command registry improvements - Console dialog components - Method signature analyzer updates - Route mapper refinements - MCP server and tool mapper updates - Queue job chain and dependency commands - Discovery tokenizer improvements Infrastructure: - Deployment architecture documentation - Ansible playbook updates for WireGuard client regeneration - Production environment configuration updates - Docker Compose local configuration updates - Remove obsolete docker-compose.yml (replaced by environment-specific configs) Documentation: - PERMISSIONS.md for access control guidelines - WireGuard DNS fix implementation details - Console dialog mode usage guide - Deployment architecture overview Testing: - Multi-purpose attribute tests - Gitea Actions integration tests (typed and untyped)
This commit is contained in:
@@ -4,7 +4,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\Mcp;
|
||||
|
||||
use App\Framework\Console\ConsoleCommand;
|
||||
use App\Framework\Core\AttributeMapper;
|
||||
use App\Framework\Core\ParameterTypeValidator;
|
||||
use App\Framework\Attributes\Route;
|
||||
use App\Framework\Mcp\Core\ValueObjects\OutputFormat;
|
||||
use App\Framework\Reflection\WrappedReflectionClass;
|
||||
use App\Framework\Reflection\WrappedReflectionMethod;
|
||||
@@ -15,6 +18,13 @@ use ReflectionUnionType;
|
||||
|
||||
final readonly class McpToolMapper implements AttributeMapper
|
||||
{
|
||||
private ParameterTypeValidator $typeValidator;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->typeValidator = new ParameterTypeValidator();
|
||||
}
|
||||
|
||||
public function getAttributeClass(): string
|
||||
{
|
||||
return McpTool::class;
|
||||
@@ -28,6 +38,26 @@ final readonly class McpToolMapper implements AttributeMapper
|
||||
|
||||
$class = $reflectionTarget->getDeclaringClass();
|
||||
|
||||
// Check if method has multiple attributes (multi-purpose)
|
||||
$hasMultipleAttributes = $this->hasMultiplePurposeAttributes($reflectionTarget);
|
||||
|
||||
// If multi-purpose, validate that all parameters are builtin types
|
||||
if ($hasMultipleAttributes) {
|
||||
$parameters = $reflectionTarget->getParameters()->toArray();
|
||||
$reflectionParameters = [];
|
||||
foreach ($parameters as $param) {
|
||||
$reflectionParameters[] = $param->getType();
|
||||
}
|
||||
|
||||
if (! $this->typeValidator->hasOnlyBuiltinParameters($reflectionParameters)) {
|
||||
// Skip this attribute if parameters are not all builtin
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Get other attributes for metadata
|
||||
$otherAttributes = $this->getOtherPurposeAttributes($reflectionTarget);
|
||||
|
||||
return [
|
||||
'name' => $attributeInstance->name,
|
||||
'description' => $attributeInstance->description,
|
||||
@@ -35,9 +65,56 @@ final readonly class McpToolMapper implements AttributeMapper
|
||||
'class' => $class->getFullyQualified(),
|
||||
'method' => $reflectionTarget->getName(),
|
||||
'parameters' => $this->extractParameters($reflectionTarget),
|
||||
'multi_purpose' => $hasMultipleAttributes,
|
||||
'other_attributes' => $otherAttributes,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if method has multiple purpose attributes (McpTool, ConsoleCommand, Route)
|
||||
*/
|
||||
private function hasMultiplePurposeAttributes(WrappedReflectionMethod $method): bool
|
||||
{
|
||||
$attributes = $method->getAttributes();
|
||||
$purposeAttributeCount = 0;
|
||||
|
||||
foreach ($attributes as $attribute) {
|
||||
$attributeName = $attribute->getName();
|
||||
if (in_array($attributeName, [
|
||||
McpTool::class,
|
||||
ConsoleCommand::class,
|
||||
Route::class,
|
||||
], true)) {
|
||||
$purposeAttributeCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return $purposeAttributeCount > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get other purpose attributes on the same method
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
private function getOtherPurposeAttributes(WrappedReflectionMethod $method): array
|
||||
{
|
||||
$attributes = $method->getAttributes();
|
||||
$otherAttributes = [];
|
||||
|
||||
foreach ($attributes as $attribute) {
|
||||
$attributeName = $attribute->getName();
|
||||
if (in_array($attributeName, [
|
||||
ConsoleCommand::class,
|
||||
Route::class,
|
||||
], true)) {
|
||||
$otherAttributes[] = $attributeName;
|
||||
}
|
||||
}
|
||||
|
||||
return $otherAttributes;
|
||||
}
|
||||
|
||||
private function generateInputSchema(WrappedReflectionMethod $method, McpTool $tool): array
|
||||
{
|
||||
$schema = [
|
||||
@@ -262,7 +339,7 @@ final readonly class McpToolMapper implements AttributeMapper
|
||||
$type = $param->getType();
|
||||
$parameters[] = [
|
||||
'name' => $param->getName(),
|
||||
'type' => $type ? $type->getName() : 'mixed',
|
||||
'type' => $type ? ($type instanceof \ReflectionNamedType ? $type->getName() : 'mixed') : 'mixed',
|
||||
'required' => ! $param->isOptional(),
|
||||
'default' => $param->isOptional() ? $param->getDefaultValue() : null,
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user