Skip to content

Commit fc0b1f9

Browse files
dmealingclaude
andcommitted
Merge FR-010 Java Plan 3: output-format prompt-fragment generator (@PromptStyle) + verify
Artifact 1: from one template.output, generate <Template>OutputPrompt.renderFormat([overrides]) producing the comment-free "produce your answer like this" prompt fragment. Adds @PromptStyle (closed enum guide|inline|exampleOnly, default guide) + @example/@instruction/@enumDoc metamodel attrs; a shared OutputFormatRenderer in render (3 styles x xml/json, never comments, valid output); OutputFormatSpecEmitter + SpringOutputPromptGenerator; Verify.checkOutputPrompt + render->recover round-trip; clean template-output-{xml,json}-simple fixtures. Compile-and-run proof. ~280 tests green (metadata 741 + render 211 + codegen-spring 71). Reviewed (caught NaN-invalid-JSON + two missing-import codegen bugs) + simplified pre-merge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2 parents 38f4e38 + 170da2e commit fc0b1f9

31 files changed

Lines changed: 2603 additions & 6 deletions
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# template-output-json-simple
2+
3+
Documents the FR-010 output codegen contract for a `template.output` with `@format: json`
4+
and `@promptStyle: inline`.
5+
6+
The fixture declares a `SupportAnswer` value-object with a string field, an enum field
7+
(with `@enumAlias` and `@enumDoc`), and an optional note field, wired to a
8+
`SupportAnswerOutput` template.
9+
10+
## Conformance notes
11+
12+
- **Java** asserts structurally: the generators emit `SupportAnswerOutputPrompt.java`
13+
(containing `OutputFormatRenderer.render(`, `PromptStyle.INLINE`, `Format.JSON`,
14+
and both `renderFormat()` overloads) and `SupportAnswerOutputParser.java`
15+
(containing `recover(`, `RecoverSchema RECOVER_SCHEMA`, `parse(`, and the
16+
`medium``OK` enumAlias entry).
17+
- Behavioral correctness is proven by the codegen-spring compile-run tests
18+
(`GeneratedOutputPromptCompileRunTest`, `GeneratedRecoverCompileRunTest`).
19+
- Byte-identical golden output is the TypeScript / cross-port concern (see
20+
`expected/` directories in sibling TS fixtures).
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme::support",
4+
"children": [
5+
{
6+
"object.value": {
7+
"name": "SupportAnswer",
8+
"children": [
9+
{
10+
"field.string": {
11+
"name": "text",
12+
"@example": "Your refund will appear in 3-5 days.",
13+
"@instruction": "One or two sentences to the customer.",
14+
"@required": true
15+
}
16+
},
17+
{
18+
"field.enum": {
19+
"name": "confidence",
20+
"@enumAlias": {
21+
"medium": "OK"
22+
},
23+
"@enumDoc": {
24+
"HIGH": "Directly supported.",
25+
"LOW": "A guess.",
26+
"OK": "Inference."
27+
},
28+
"@required": true,
29+
"@values": [
30+
"HIGH",
31+
"OK",
32+
"LOW"
33+
]
34+
}
35+
},
36+
{
37+
"field.string": {
38+
"name": "note"
39+
}
40+
}
41+
]
42+
}
43+
},
44+
{
45+
"template.output": {
46+
"name": "SupportAnswerOutput",
47+
"@format": "json",
48+
"@payloadRef": "SupportAnswer",
49+
"@promptStyle": "inline",
50+
"@textRef": "support/answer"
51+
}
52+
}
53+
]
54+
}
55+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme::support",
4+
"children": [
5+
{
6+
"object.value": {
7+
"name": "SupportAnswer",
8+
"children": [
9+
{ "field.string": { "name": "text", "@required": true, "@example": "Your refund will appear in 3-5 days.", "@instruction": "One or two sentences to the customer." } },
10+
{ "field.enum": { "name": "confidence", "@required": true, "@values": ["HIGH","OK","LOW"], "@enumAlias": { "medium": "OK" }, "@enumDoc": { "HIGH": "Directly supported.", "OK": "Inference.", "LOW": "A guess." } } },
11+
{ "field.string": { "name": "note" } }
12+
]
13+
}
14+
},
15+
{
16+
"template.output": {
17+
"name": "SupportAnswerOutput",
18+
"@payloadRef": "SupportAnswer",
19+
"@textRef": "support/answer",
20+
"@format": "json",
21+
"@promptStyle": "inline"
22+
}
23+
}
24+
]
25+
}
26+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# template-output-xml-simple
2+
3+
Documents the FR-010 output codegen contract for a `template.output` with `@format: xml`
4+
and `@promptStyle: guide`.
5+
6+
The fixture declares the same `SupportAnswer` value-object as `template-output-json-simple`
7+
(string field, enum field with `@enumAlias` and `@enumDoc`, optional note), wired to a
8+
`SupportAnswerOutput` template with XML format and guide prompt style.
9+
10+
## Conformance notes
11+
12+
- **Java** asserts structurally: the generators emit `SupportAnswerOutputPrompt.java`
13+
(containing `OutputFormatRenderer.render(`, `PromptStyle.GUIDE`, `Format.XML`,
14+
and both `renderFormat()` overloads) and `SupportAnswerOutputParser.java`
15+
(containing `recover(`, `RecoverSchema RECOVER_SCHEMA`, `parse(`, and the
16+
`medium``OK` enumAlias entry).
17+
- Behavioral correctness is proven by the codegen-spring compile-run tests
18+
(`GeneratedOutputPromptCompileRunTest`, `GeneratedRecoverCompileRunTest`).
19+
- Byte-identical golden output is the TypeScript / cross-port concern (see
20+
`expected/` directories in sibling TS fixtures).
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme::support",
4+
"children": [
5+
{
6+
"object.value": {
7+
"name": "SupportAnswer",
8+
"children": [
9+
{
10+
"field.string": {
11+
"name": "text",
12+
"@example": "Your refund will appear in 3-5 days.",
13+
"@instruction": "One or two sentences to the customer.",
14+
"@required": true
15+
}
16+
},
17+
{
18+
"field.enum": {
19+
"name": "confidence",
20+
"@enumAlias": {
21+
"medium": "OK"
22+
},
23+
"@enumDoc": {
24+
"HIGH": "Directly supported.",
25+
"LOW": "A guess.",
26+
"OK": "Inference."
27+
},
28+
"@required": true,
29+
"@values": [
30+
"HIGH",
31+
"OK",
32+
"LOW"
33+
]
34+
}
35+
},
36+
{
37+
"field.string": {
38+
"name": "note"
39+
}
40+
}
41+
]
42+
}
43+
},
44+
{
45+
"template.output": {
46+
"name": "SupportAnswerOutput",
47+
"@format": "xml",
48+
"@payloadRef": "SupportAnswer",
49+
"@promptStyle": "guide",
50+
"@textRef": "support/answer"
51+
}
52+
}
53+
]
54+
}
55+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"metadata.root": {
3+
"package": "acme::support",
4+
"children": [
5+
{
6+
"object.value": {
7+
"name": "SupportAnswer",
8+
"children": [
9+
{ "field.string": { "name": "text", "@required": true, "@example": "Your refund will appear in 3-5 days.", "@instruction": "One or two sentences to the customer." } },
10+
{ "field.enum": { "name": "confidence", "@required": true, "@values": ["HIGH","OK","LOW"], "@enumAlias": { "medium": "OK" }, "@enumDoc": { "HIGH": "Directly supported.", "OK": "Inference.", "LOW": "A guess." } } },
11+
{ "field.string": { "name": "note" } }
12+
]
13+
}
14+
},
15+
{
16+
"template.output": {
17+
"name": "SupportAnswerOutput",
18+
"@payloadRef": "SupportAnswer",
19+
"@textRef": "support/answer",
20+
"@format": "xml",
21+
"@promptStyle": "guide"
22+
}
23+
}
24+
]
25+
}
26+
}

0 commit comments

Comments
 (0)