[Server] Untangle origin tracking from Registry (#302)
Drop the isManual flag from ElementReference and the discovery-state methods from RegistryInterface. The Registry becomes a flat last-write-wins map; DiscoveryLoader owns its own owned-set bookkeeping so re-running discovery only removes elements it itself contributed. Adds ChainLoader for explicit composition. Manual-over-discovered precedence is preserved via loader ordering, not a flag on the reference.
This commit is contained in:
parent
e00450a218
commit
967c5cda4d
1 changed files with 1003 additions and 338 deletions
|
|
@ -19,6 +19,7 @@ use Mcp\Capability\Registry;
|
|||
use Mcp\Capability\Registry\Container;
|
||||
use Mcp\Capability\Registry\ElementReference;
|
||||
use Mcp\Capability\Registry\Loader\ArrayLoader;
|
||||
use Mcp\Capability\Registry\Loader\ChainLoader;
|
||||
use Mcp\Capability\Registry\Loader\DiscoveryLoader;
|
||||
use Mcp\Capability\Registry\Loader\LoaderInterface;
|
||||
use Mcp\Capability\Registry\ReferenceHandler;
|
||||
|
|
@ -540,11 +541,6 @@ final class Builder
|
|||
$container = $this->container ?? new Container();
|
||||
$registry = $this->registry ?? new Registry($this->eventDispatcher, $logger);
|
||||
$subscriptionManager = $this->subscriptionManager ?? new SessionSubscriptionManager($logger);
|
||||
$loaders = [
|
||||
...$this->loaders,
|
||||
new ArrayLoader($this->tools, $this->resources, $this->resourceTemplates, $this->prompts, $logger, $this->schemaGenerator),
|
||||
];
|
||||
|
||||
$sessionManager = $this->sessionManager ?? new SessionManager(
|
||||
$this->sessionStore ?? new InMemorySessionStore(),
|
||||
$logger,
|
||||
|
|
@ -552,18 +548,24 @@ final class Builder
|
|||
$this->gcDivisor,
|
||||
);
|
||||
|
||||
// ArrayLoader runs before DiscoveryLoader so manual entries are seen first; DiscoveryLoader's
|
||||
// identity check then preserves them against same-name discovered entries.
|
||||
$loaders = [
|
||||
...$this->loaders,
|
||||
new ArrayLoader($this->tools, $this->resources, $this->resourceTemplates, $this->prompts, $logger, $this->schemaGenerator),
|
||||
];
|
||||
|
||||
if (null !== $this->discoveryBasePath) {
|
||||
if (null !== $this->discoverer || class_exists(Finder::class)) {
|
||||
$discoverer = $this->discoverer ?? $this->createDiscoverer($logger);
|
||||
$loaders[] = new DiscoveryLoader($this->discoveryBasePath, $this->discoveryScanDirs, $this->discoveryExcludeDirs, $discoverer, $this->discoveryNamePatterns);
|
||||
$loaders[] = new DiscoveryLoader($this->discoveryBasePath, $this->discoveryScanDirs, $this->discoveryExcludeDirs, $discoverer, $this->discoveryNamePatterns, $logger);
|
||||
} else {
|
||||
$logger->warning('File-based discovery requires symfony/finder. Skipping automatic discovery. Run: composer require symfony/finder');
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($loaders as $loader) {
|
||||
$loader->load($registry);
|
||||
}
|
||||
$loader = new ChainLoader($loaders);
|
||||
$loader->load($registry);
|
||||
|
||||
$messageFactory = MessageFactory::make();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue