Example: Response-Only

A direct-answer flow. The agent's closing message is the deliverable — no file is emitted, no JSON is parsed.


Spec

json
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

yaml
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

ts
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 →