Example: Response-Only
A direct-answer flow. The agent's closing message is the deliverable — no file is emitted, no JSON is parsed.
Spec
1{
2 "ref": "commit-review-summary",
3 "kind": "response-only",
4 "outputContract": {
5 "title": "Commit Review Summary",
6 "mode": "response-only"
7 }
8}response-only specs cannot declare files[], multiPage, or targetSlot — the schema rejects those fields for this mode.
Workflow
1apiVersion: xema.dev/workflow/v1alpha1
2kind: Workflow
3metadata:
4 name: commit-review-example
5 version: 1.0.0
6on:
7 webhook:
8 accepted_kinds: [SCM_PR_OPENED, SCM_PR_UPDATED]
9permissions:
10 artifacts: write
11jobs:
12 checkout:
13 uses: software-dev/scm-[email protected]
14 with:
15 repoRef: ${{ trigger.payload.repoRef }}
16 ref: ${{ trigger.payload.headSha }}
17
18 review:
19 needs: [checkout]
20 uses: xema/agent
21 with:
22 agentRef: gate-reviewer-quality
23 stageKey: utility
24 deliverableSpecRef: commit-review-summary
25 agentSession: false
26 agentContext:
27 prompt: ${{ format('Review the diff at {0}', trigger.payload.diffUrl) }}
28 repoRef: ${{ trigger.payload.repoRef }}
29 changeRequestId: ${{ trigger.payload.changeRequestId }}
30 headSha: ${{ trigger.payload.headSha }}
31 baseSha: ${{ trigger.payload.baseSha }}
32 diffUrl: ${{ trigger.payload.diffUrl }}
33 outputs:
34 summary: ${{ job.outputs.deliverable.content.text }}
35
36 post-review:
37 needs: [review]
38 uses: software-dev/scm-post-[email protected]
39 with:
40 changeRequestId: ${{ trigger.payload.changeRequestId }}
41 body: ${{ needs.review.outputs.summary }}Reading the result
1agentResult: {
2 deliverable: {
3 specRef: 'commit-review-summary',
4 kind: 'response-only',
5 targetSlot: { kind: 'deliverables' }, // unused for response-only
6 content: {
7 kind: 'response',
8 text: '## Commit Review\n\n- Looks good overall\n- Minor: prefer const for line 42...',
9 },
10 },
11}deliverable.content.text carries the agent's closing assistant message verbatim. Downstream scm-post-review posts it as a PR comment.
Validating the result
A response-only spec with no content accepts free-form text, so there is no shape to check — the spec author's prompt is what elicits the right response.
A response-only spec that does carry content is different: content must be a JSON Schema object, and it is enforced at inference time. The activity passes it to the runtime as outputFormat: { type: 'json_schema', schema } so the structured-output tool validates the answer as the agent produces it, rather than after the fact.
Either way, xema/validate-deliverables downstream still gives the workflow a verdict to branch on — for a response-only spec its built-in rules are the artifact-count rules. See 04 Validation.
Previous: ← Code into a repo Next: Matrix mixed kinds →