feat(enricher): enriched context, rewritten templates, custom prompts#64
feat(enricher): enriched context, rewritten templates, custom prompts#64spencercjh merged 17 commits intomainfrom
Conversation
…ldContext, and TemplateContext Signed-off-by: spencercjh <spencercjh@gmail.com>
… in schema field collection Signed-off-by: spencercjh <spencercjh@gmail.com>
…aints) in parameter and API collection - Add buildParamConstraintsString and buildParamEnumStrings helper functions - Extract format, enum, constraints from parameter schemas during collection - Populate Tags, ExistingSummary, ExistingDescription for API operations - Add tests for enriched parameter context and API tags Signed-off-by: spencercjh <spencercjh@gmail.com>
…ompts, few-shot examples, and enriched context Signed-off-by: spencercjh <spencercjh@gmail.com>
…cher pipeline - Add CustomPromptCfg to config.EnrichConfig for per-type prompt overrides - Add CustomPromptConfig to enricher.Config with System/User fields - Apply custom prompts via TemplateManager.Set() in enricher.Enrich() - Wire custom prompts mapping in both cmd/enrich.go and cmd/generate.go - Document customPrompts section in .spec-forge.example.yaml Signed-off-by: spencercjh <spencercjh@gmail.com>
- Fix perfsprint lint: replace fmt.Sprintf with string concatenation for pattern strings - Fix gocritic rangeValCopy: add nolint comments for acceptable struct copies - Add TestEnricher_CustomPrompts integration test verifying custom template overrides Signed-off-by: spencercjh <spencercjh@gmail.com>
Signed-off-by: spencercjh <spencercjh@gmail.com>
…umStrings helpers Remove duplicated constraint/enum helpers from enricher.go and reuse the exported versions from the processor package. Signed-off-by: spencercjh <spencercjh@gmail.com>
Log a warning when a customPrompts config key is not one of the valid template types (api, schema, param, response) instead of silently creating an unusable template. Signed-off-by: spencercjh <spencercjh@gmail.com>
Parse system and user templates when Set() is called so that syntax errors are caught early instead of failing silently during batch processing. Signed-off-by: spencercjh <spencercjh@gmail.com>
Extract CustomPromptsFromMap into enricher/config.go and use it from both cmd/enrich.go and cmd/generate.go to eliminate the identical mapping blocks. Signed-off-by: spencercjh <spencercjh@gmail.com>
There was a problem hiding this comment.
Pull request overview
This PR improves the enricher’s prompt quality and flexibility by passing richer OpenAPI metadata into prompt templates, rewriting the built-in prompt templates, and adding .spec-forge.yaml support for user-defined prompt overrides.
Changes:
- Enrich prompt context with OpenAPI metadata (format, enums, constraints, tags, existing descriptions).
- Rewrite built-in prompt templates (API/schema/param/response) with clearer guidance and few-shot examples.
- Add
customPromptsconfiguration plumbing (config → CLI → enricher) with template parse validation and warnings on invalid keys.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| internal/enricher/prompt/templates.go | Adds enriched context fields, join template func, rewrites built-in prompts, and validates custom templates in Set() |
| internal/enricher/prompt/templates_test.go | Adds tests ensuring enriched context renders across all template types and tags are included |
| internal/enricher/processor/schema.go | Populates schema field enriched metadata; exports enum/constraint helper builders |
| internal/enricher/processor/schema_test.go | Tests schema field enrichment for constraints/enum/format |
| internal/enricher/processor/processor.go | Extends FieldElement/ParamFieldItem and propagates enriched metadata into prompt contexts |
| internal/enricher/processor/batch.go | Adds a linter suppression comment for param range-copy behavior |
| internal/enricher/enricher.go | Applies custom prompts; passes API tags/existing docs; enriches parameter context with enum/constraints/format |
| internal/enricher/enricher_test.go | Adds tests for enriched param context, API tags propagation, and custom prompt overrides |
| internal/enricher/config.go | Introduces enricher-layer CustomPromptConfig and mapping helper from config-layer types |
| internal/config/config.go | Adds customPrompts to EnrichConfig and defines CustomPromptCfg |
| cmd/enrich.go | Wires customPrompts from loaded config into enricher config |
| cmd/generate.go | Wires customPrompts into the generate→enrich pipeline |
| .spec-forge.example.yaml | Documents enrich.customPrompts configuration |
| docs/plans/2026-03-31-p5-prompt-optimization-design.md | Design documentation for the prompt optimization work |
| docs/plans/2026-03-31-p5-prompt-optimization-implementation.md | Implementation plan / checklist for the prompt optimization work |
Comments suppressed due to low confidence (1)
internal/enricher/enricher.go:322
- ParamFieldItem includes an ExistingDescription field (and the param prompt template renders it), but collectParameterGroups never populates it. In --force mode this means custom/built-in templates won't receive the existing parameter description from the spec, reducing the intended “rewrite/translate existing docs” behavior. Consider setting ExistingDescription from param.Description when building ParamFieldItem (and keep the SetValue closure writing back to param.Description).
param := paramRef.Value
fieldType := ""
format := ""
var enum []string
var constraints string
if param.Schema != nil && param.Schema.Value != nil {
schemaVal := param.Schema.Value
fieldType = getSchemaTypeString(schemaVal)
format = schemaVal.Format
enum = processor.BuildEnumStrings(schemaVal.Enum)
constraints = processor.BuildConstraintsString(schemaVal)
}
// Capture for closure
p := param
params = append(params, processor.ParamFieldItem{
ParamName: param.Name,
ParamIn: param.In,
FieldType: fieldType,
Required: param.Required,
Format: format,
Enum: enum,
Constraints: constraints,
SetValue: func(desc string) {
p.Description = desc
},
})
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Format is now a first-class field rendered separately by templates, so embedding it in FieldType via getSchemaTypeString is redundant. Signed-off-by: spencercjh <spencercjh@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ParamFieldItem was missing ExistingDescription, causing --force mode prompts to render empty existing descriptions for parameters. Signed-off-by: spencercjh <spencercjh@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…eplace recursive contains with strings.Contains Signed-off-by: spencercjh <spencercjh@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…t empty user Custom prompts now merge with built-in templates — only non-empty fields override built-in content. Empty user templates are rejected at Set() to prevent silent failures. Updated example config to show both fields. Signed-off-by: spencercjh <spencercjh@gmail.com>
…matic complexity Signed-off-by: spencercjh <spencercjh@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…tes and add nil check in Set Remove double-quote wrapping of ExistingDescription in schema and param templates to avoid broken prompts when descriptions contain quotes or newlines. Add nil template guard in TemplateManager.Set. Signed-off-by: spencercjh <spencercjh@gmail.com>
Summary
.spec-forge.yaml, with startup validation and warning on invalid keysCloses #63
Changes
internal/enricher/prompt/templates.gojoinFuncMap; template validation onSet()internal/enricher/processor/schema.goBuildConstraintsString/BuildEnumStringsshared helpersinternal/enricher/processor/processor.goFieldElement,ParamFieldItem, convertersinternal/enricher/enricher.gointernal/enricher/config.goCustomPromptConfig,CustomPromptsFromMaphelperinternal/config/config.goCustomPromptstoEnrichConfigcmd/enrich.go,cmd/generate.go.spec-forge.example.yamlcustomPromptssectiondocs/plans/Test plan
make test— all tests passmake lint— 0 issuesTestEnricher_CustomPrompts)