Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions docs/example/config/prompt-templates.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
prompts:
# Template for issues
- id: template-issue
description: Template for creating issues
type: template
messages:
- role: user
content: "Create a new issue with the following title and description: {{title}} {{description}}"

# Template for bug issues, extending the base issue template
- id: bug-issue
description: Create a new bug issue
type: prompt
extend:
- id: template-issue
arguments:
title: 'Bug: {{title}}'
description: '{{description}}'
schema:
properties:
title:
description: The title of the bug
description:
description: The description of the bug
required:
- title
- description

# Template for feature issues, extending the base issue template
- id: feature-issue
description: Create a new feature issue
type: prompt
extend:
- id: template-issue
arguments:
title: 'Feature: {{title}}'
description: '{{description}}'
schema:
properties:
title:
description: The title of the feature
description:
description: The description of the feature
required:
- title
- description

# More complex template example, extending another template
- id: template-complex-issue
type: template
description: Template for complex issues with priority
extend:
- id: template-issue
arguments:
title: '{{type}}: {{title}}'
description: '{{description}} \n\n**Priority**: {{priority}}'

# Priority bug issue using the complex template
- id: priority-bug-issue
description: Create a new priority bug issue
type: prompt
extend:
- id: template-complex-issue
arguments:
type: 'Bug'
priority: 'High'
schema:
properties:
title:
description: The title of the bug
description:
description: The description of the bug
required:
- title
- description
110 changes: 99 additions & 11 deletions json-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,10 @@
},
"type": {
"type": "string",
"enum": ["run", "http"],
"enum": [
"run",
"http"
],
"description": "Type of tool (run = command execution, http = HTTP requests)",
"default": "run"
},
Expand Down Expand Up @@ -309,7 +312,9 @@
}
},
"then": {
"required": ["commands"]
"required": [
"commands"
]
}
},
{
Expand All @@ -321,22 +326,34 @@
}
},
"then": {
"required": ["requests"]
"required": [
"requests"
]
}
}
]
},
"httpRequest": {
"type": "object",
"required": ["url"],
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"description": "URL to send the request to, may contain {{argument}} placeholders"
},
"method": {
"type": "string",
"enum": ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"],
"enum": [
"GET",
"POST",
"PUT",
"DELETE",
"PATCH",
"HEAD",
"OPTIONS"
],
"description": "HTTP method to use",
"default": "GET"
},
Expand Down Expand Up @@ -423,8 +440,7 @@
"prompt": {
"type": "object",
"required": [
"id",
"messages"
"id"
],
"properties": {
"id": {
Expand All @@ -435,6 +451,15 @@
"type": "string",
"description": "Human-readable description of the prompt"
},
"type": {
"type": "string",
"enum": [
"prompt",
"template"
],
"description": "Type of prompt (regular prompt or template)",
"default": "prompt"
},
"schema": {
"$ref": "#/definitions/inputSchema",
"description": "Defines input parameters for this prompt"
Expand All @@ -459,13 +484,74 @@
},
"content": {
"type": "string",
"description": "The content of the message, may contain variable placeholders like ${variableName}"
"description": "The content of the message, may contain variable placeholders like ${variableName} or {{variableName}}"
}
}
}
},
"extend": {
"type": "array",
"description": "List of templates to extend",
"items": {
"type": "object",
"required": [
"id"
],
"properties": {
"id": {
"type": "string",
"description": "ID of the template to extend"
},
"arguments": {
"type": "object",
"description": "Arguments to pass to the template",
"additionalProperties": {
"type": "string"
}
}
}
}
}
},
"allOf": [
{
"if": {
"properties": {
"type": {
"const": "prompt"
}
}
},
"minItems": 1
"then": {
"anyOf": [
{
"required": [
"messages"
]
},
{
"required": [
"extend"
]
}
]
}
},
{
"if": {
"properties": {
"type": {
"const": "template"
}
}
},
"then": {
"required": [
"messages"
]
}
}
}
]
},
"document": {
"type": "object",
Expand Down Expand Up @@ -1257,7 +1343,9 @@
"description": "Patterns to include only specific paths"
},
"maxFiles": {
"type": ["integer"],
"type": [
"integer"
],
"description": "Maximum number of files to include (0 for no limit)",
"minimum": 0,
"default": 0
Expand Down
9 changes: 9 additions & 0 deletions src/Application/Bootloader/VariableBootloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@

use Butschster\ContextGenerator\Config\Parser\VariablesParserPlugin;
use Butschster\ContextGenerator\DirectoriesInterface;
use Butschster\ContextGenerator\Lib\Variable\CompositeProcessor;
use Butschster\ContextGenerator\Lib\Variable\Provider\CompositeVariableProvider;
use Butschster\ContextGenerator\Lib\Variable\Provider\ConfigVariableProvider;
use Butschster\ContextGenerator\Lib\Variable\Provider\DotEnvVariableProvider;
use Butschster\ContextGenerator\Lib\Variable\Provider\PredefinedVariableProvider;
use Butschster\ContextGenerator\Lib\Variable\Provider\VariableProviderInterface;
use Butschster\ContextGenerator\Lib\Variable\VariableReplacementProcessor;
use Butschster\ContextGenerator\Lib\Variable\VariableReplacementProcessorInterface;
use Butschster\ContextGenerator\Lib\Variable\VariableResolver;
use Dotenv\Repository\RepositoryBuilder;
use Spiral\Boot\Bootloader\Bootloader;
Expand Down Expand Up @@ -50,6 +53,12 @@ public function defineSingletons(): array
);
},

VariableReplacementProcessorInterface::class => static fn(
VariableReplacementProcessor $replacementProcessor,
) => new CompositeProcessor([
$replacementProcessor,
]),

VariableResolver::class => VariableResolver::class,
];
}
Expand Down
5 changes: 4 additions & 1 deletion src/Console/GenerateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@ public function __invoke(Container $container, DirectoriesInterface $dirs): int

$config = new ConfigRegistryAccessor($loader->load());

$renderer->renderImports($config->getImports());
$imports = $config->getImports();
if ($imports !== null) {
$renderer->renderImports($imports);
}

foreach ($config->getDocuments() as $document) {
$this->logger->info(\sprintf('Compiling %s...', $document->description));
Expand Down
22 changes: 21 additions & 1 deletion src/Document/DocumentRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
/**
* @implements RegistryInterface<Document>
*/
final class DocumentRegistry implements RegistryInterface
final class DocumentRegistry implements RegistryInterface, \ArrayAccess

Check failure on line 12 in src/Document/DocumentRegistry.php

View workflow job for this annotation

GitHub Actions / psalm (ubuntu-latest, 8.3, locked)

MissingTemplateParam

src/Document/DocumentRegistry.php:12:60: MissingTemplateParam: Butschster\ContextGenerator\Document\DocumentRegistry has missing template params when extending ArrayAccess, expecting 2 (see https://psalm.dev/182)

Check failure on line 12 in src/Document/DocumentRegistry.php

View workflow job for this annotation

GitHub Actions / psalm (ubuntu-latest, 8.3, locked)

MissingTemplateParam

src/Document/DocumentRegistry.php:12:60: MissingTemplateParam: Butschster\ContextGenerator\Document\DocumentRegistry has missing template params when extending ArrayAccess, expecting 2 (see https://psalm.dev/182)
{
public function __construct(
/** @var array<Document> */
Expand Down Expand Up @@ -45,4 +45,24 @@
{
return new \ArrayIterator($this->getItems());
}

public function offsetExists(mixed $offset): bool
{
return \array_key_exists($offset, $this->documents);
}

public function offsetGet(mixed $offset): mixed
{
return $this->documents[$offset] ?? null;
}

public function offsetSet(mixed $offset, mixed $value): void
{
throw new \BadMethodCallException('Cannot set value directly. Use register() method.');
}

public function offsetUnset(mixed $offset): void
{
throw new \BadMethodCallException('Cannot unset value directly.');
}
}
24 changes: 24 additions & 0 deletions src/Lib/Variable/CompositeProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Butschster\ContextGenerator\Lib\Variable;

final readonly class CompositeProcessor implements VariableReplacementProcessorInterface
{
/**
* @param VariableReplacementProcessor[] $processors
*/
public function __construct(
public array $processors = [],
) {}

public function process(string $text): string
{
foreach ($this->processors as $processor) {
$text = $processor->process($text);
}

return $text;
}
}
2 changes: 1 addition & 1 deletion src/Lib/Variable/VariableReplacementProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/**
* Processor that replaces variable references in text
*/
final readonly class VariableReplacementProcessor
final readonly class VariableReplacementProcessor implements VariableReplacementProcessorInterface
{
public function __construct(
private VariableProviderInterface $provider = new PredefinedVariableProvider(),
Expand Down
16 changes: 16 additions & 0 deletions src/Lib/Variable/VariableReplacementProcessorInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace Butschster\ContextGenerator\Lib\Variable;

interface VariableReplacementProcessorInterface
{
/**
* Process text by replacing variable references
*
* @param string $text Text containing variable references
* @return string Text with variables replaced
*/
public function process(string $text): string;
}
10 changes: 9 additions & 1 deletion src/Lib/Variable/VariableResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,17 @@
final readonly class VariableResolver
{
public function __construct(
private VariableReplacementProcessor $processor = new VariableReplacementProcessor(),
private VariableReplacementProcessorInterface $processor = new CompositeProcessor(),
) {}

public function with(VariableReplacementProcessorInterface $processor): self
{
return new self(new CompositeProcessor([
$this->processor,
$processor,
]));
}

/**
* Resolve variables in the given text
*/
Expand Down
Loading
Loading