Skip to content

Commit efc8a57

Browse files
authored
Merge pull request #209 from context-hub/bugfix/import-resolver
feat: Enhance import handling and add comprehensive local import tests
2 parents d2aee6f + f9b86aa commit efc8a57

24 files changed

+4175
-73
lines changed

src/Config/Import/ImportParserPlugin.php

+9
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ public function updateConfig(array $config, string $rootPath): array
5050
return $config;
5151
}
5252

53+
if (!\is_array($config['import'])) {
54+
$this->logger?->warning('Invalid import configuration', [
55+
'config' => $config['import'],
56+
]);
57+
58+
return $config;
59+
}
60+
5361
$this->logger?->debug('Processing imports', [
5462
'rootPath' => $rootPath,
5563
'importCount' => \count($config['import']),
@@ -61,6 +69,7 @@ public function updateConfig(array $config, string $rootPath): array
6169
foreach ($processedConfig->imports as $import) {
6270
$this->registry->register($import);
6371
}
72+
6473
$this->logger?->debug('Imports processed successfully');
6574

6675
return $processedConfig->config;

src/Config/Import/ImportRegistry.php

+1-3
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@ public function getItems(): array
4141

4242
public function jsonSerialize(): array
4343
{
44-
return [
45-
'imports' => $this->imports,
46-
];
44+
return $this->imports;
4745
}
4846

4947
public function getIterator(): \Traversable

src/Config/Import/ImportResolver.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,7 @@ private function processSingleImport(
251251
'type' => $sourceConfig->getType(),
252252
'error' => $e->getMessage(),
253253
]);
254-
255-
throw $e;
254+
// Ignore the error if the import is broken
256255
} finally {
257256
// Always end processing to maintain stack integrity
258257
$this->detector->endProcessing($importId);

src/Config/Import/Source/ImportSourceProvider.php

+8-24
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,19 @@
44

55
namespace Butschster\ContextGenerator\Config\Import\Source;
66

7-
use Butschster\ContextGenerator\Application\Logger\HasPrefixLoggerInterface;
87
use Butschster\ContextGenerator\Application\Logger\LoggerPrefix;
98
use Butschster\ContextGenerator\Config\Import\Source\Config\SourceConfigInterface;
109
use Butschster\ContextGenerator\Config\Import\Source\Registry\ImportSourceRegistry;
1110
use Psr\Log\LoggerInterface;
12-
use Psr\Log\NullLogger;
11+
use Spiral\Core\Container;
1312

1413
/**
1514
* Service provider for accessing import sources
1615
*/
1716
final readonly class ImportSourceProvider
1817
{
1918
public function __construct(
20-
private ImportSourceRegistry $sourceRegistry,
19+
private Container $container,
2120
#[LoggerPrefix(prefix: 'import-sources')]
2221
private ?LoggerInterface $logger = null,
2322
) {}
@@ -31,7 +30,7 @@ public function __construct(
3130
*/
3231
public function getSource(string $name): ImportSourceInterface
3332
{
34-
return $this->sourceRegistry->get($name);
33+
return $this->getSourceRegistry()->get($name);
3534
}
3635

3736
/**
@@ -44,15 +43,15 @@ public function findSourceForConfig(SourceConfigInterface $config): ?ImportSourc
4443
{
4544
// First try to find source by type
4645
$sourceName = $config->getType();
47-
if ($this->sourceRegistry->has($sourceName)) {
48-
$source = $this->sourceRegistry->get($sourceName);
46+
if ($this->getSourceRegistry()->has($sourceName)) {
47+
$source = $this->getSourceRegistry()->get($sourceName);
4948
if ($source->supports($config)) {
5049
return clone $source;
5150
}
5251
}
5352

5453
// If not found by type, try all registered sources
55-
foreach ($this->sourceRegistry->all() as $source) {
54+
foreach ($this->getSourceRegistry()->all() as $source) {
5655
if ($source->supports($config)) {
5756
return clone $source;
5857
}
@@ -66,23 +65,8 @@ public function findSourceForConfig(SourceConfigInterface $config): ?ImportSourc
6665
return null;
6766
}
6867

69-
/**
70-
* Get a logger with a source-specific prefix
71-
*
72-
* @param string $sourceName Name of the source for logger prefixing
73-
* @return LoggerInterface Logger with appropriate prefix
74-
*/
75-
public function getSourceLogger(string $sourceName): LoggerInterface
68+
private function getSourceRegistry(): ImportSourceRegistry
7669
{
77-
if ($this->logger === null) {
78-
return new NullLogger();
79-
}
80-
81-
// Check if logger supports prefixing
82-
if ($this->logger instanceof HasPrefixLoggerInterface) {
83-
return $this->logger->withPrefix("import-{$sourceName}");
84-
}
85-
86-
return $this->logger;
70+
return $this->container->get(ImportSourceRegistry::class);
8771
}
8872
}

src/Config/Import/Source/Url/UrlImportSource.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public function load(SourceConfigInterface $config): array
6161
}
6262

6363
try {
64-
$url = $config->url;
64+
$url = $this->container->get(VariableResolver::class)->resolve($config->url);
6565
$headers = $this->container->get(VariableResolver::class)->resolve($config->headers);
6666

6767
$this->logger->debug('Loading URL import', [

src/Console/GenerateCommand.php

+7-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ public function __invoke(Container $container, DirectoriesInterface $dirs): int
127127
$config = new ConfigRegistryAccessor($loader->load());
128128

129129
$imports = $config->getImports();
130-
if ($imports !== null) {
130+
if ($imports !== null && !$this->asJson) {
131131
$renderer->renderImports($imports);
132132
}
133133

@@ -136,6 +136,9 @@ public function __invoke(Container $container, DirectoriesInterface $dirs): int
136136
$this->output->writeln(\json_encode([
137137
'status' => 'success',
138138
'message' => 'No documents found in configuration.',
139+
'imports' => $imports,
140+
'prompts' => $config->getPrompts(),
141+
'tools' => $config->getTools(),
139142
]));
140143
} else {
141144
$this->output->warning('No documents found in configuration.');
@@ -167,6 +170,9 @@ public function __invoke(Container $container, DirectoriesInterface $dirs): int
167170
'status' => 'success',
168171
'message' => 'Documents compiled successfully',
169172
'result' => $result,
173+
'imports' => $imports,
174+
'prompts' => $config->getPrompts(),
175+
'tools' => $config->getTools(),
170176
]));
171177
} else {
172178
$this->output->writeln('');

src/McpServer/Prompt/PromptConfigFactory.php

+23
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,21 @@ public function createFromConfig(array $config): PromptDefinition
5757
$tags = $this->parseTags($config['tags']);
5858
}
5959

60+
// Validate that prompts have instructions (messages or extensions)
61+
// Templates can have empty messages as they may be just structural
62+
if ($type === PromptType::Prompt && empty($messages) && empty($extensions)) {
63+
throw new PromptParsingException(
64+
\sprintf('Prompt "%s" must have either messages or extend a template', $config['id']),
65+
);
66+
}
67+
68+
// Templates should have messages to be useful for extension
69+
if ($type === PromptType::Template && empty($messages)) {
70+
throw new PromptParsingException(
71+
\sprintf('Template "%s" must have messages to be extended by prompts', $config['id']),
72+
);
73+
}
74+
6075
return new PromptDefinition(
6176
id: $config['id'],
6277
prompt: new Prompt(
@@ -110,6 +125,10 @@ private function parseTags(array $tagsConfig): array
110125
*/
111126
private function parseExtensions(array $extensionConfigs): array
112127
{
128+
if (empty($extensionConfigs)) {
129+
return [];
130+
}
131+
113132
$extensions = [];
114133

115134
foreach ($extensionConfigs as $index => $extensionConfig) {
@@ -185,6 +204,10 @@ private function createArgumentsFromSchema(?array $schema): array
185204
*/
186205
private function parseMessages(array $messagesConfig): array
187206
{
207+
if (empty($messagesConfig)) {
208+
return [];
209+
}
210+
188211
$messages = [];
189212

190213
foreach ($messagesConfig as $index => $messageConfig) {

src/McpServer/Prompt/PromptRegistry.php

+1-4
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,7 @@ public function getItems(): array
8686

8787
public function jsonSerialize(): array
8888
{
89-
// Only serialize regular prompts, not templates
90-
return [
91-
'prompts' => $this->getItems(),
92-
];
89+
return $this->getItems();
9390
}
9491

9592
public function getIterator(): \Traversable

src/McpServer/Tool/ToolRegistry.php

+1-3
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,7 @@ public function getItems(): array
6060

6161
public function jsonSerialize(): array
6262
{
63-
return [
64-
'tools' => $this->getItems(),
65-
];
63+
return $this->getItems();
6664
}
6765

6866
public function getIterator(): \Traversable

0 commit comments

Comments
 (0)