You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An AgentTemplate can now constrain its answer to a JSON Schema, and the 1.x doc set does not mention the feature anywhere. kagent#2890 landed the CRD fields, the translator, the runtime validation, the A2A response contract, the CLI, and the UI, so a reader can configure structured output today with nothing in the docs to tell them how.
This is new writing rather than an edit.
What the page covers
Declaring a JSON Schema for an agent's successful terminal response, and what the runtime does with a response that does not match.
The spine of the page is that the schema is a compile-time contract, not a request-time hint. The translator resolves the schema, validates it against a portable profile, and records a canonical form and digest in the immutable prepared revision. A schema the profile rejects fails compilation, so no agent runs at all, rather than failing later at inference. Lead with that and the admission rules below stop looking like a list of restrictions and start looking like one decision.
Upstream wrote the design document first.docs/architecture/structured-output.md is unusually complete and is the right starting point. It is an architecture document rather than a task guide, so it is a source, not a draft.
A name and key selecting a same-namespace ConfigMap that holds the schema as JSON.
Admission rules.
A CEL rule rejects a template that sets both, with the message outputSchema and outputSchemaFrom are mutually exclusive.
The schema must have an object root.
The portable profile supports primitive JSON types, nested objects and arrays, properties, required, additionalProperties, items, enum, const, anyOf, titles and descriptions, and non-recursive local references through $defs. External references, recursive references, conditional schemas and tuple arrays are rejected at compile time rather than silently weakened for a provider.
The serialized schema is limited to 64 KiB, and conversion is limited to 32 levels and 1,000 expanded nodes. Nodes reached through $defs count toward both bounds.
Only the kagent Harness supports structured output. The codex, claude and byo Harnesses fail compilation with Harness "<name>" does not support structured output.
Behavior the API does not announce
Two different conditions report a failure, and which one fires depends on what went wrong. An invalid schema, or a Harness that cannot run it, sets the Compatible condition to False with the reason UnsupportedConfiguration. A ConfigMap that does not exist, or a key that is missing from it, sets ResolvedRefs to False with the reason ReferenceResolutionFailed. A reader debugging a template needs to know which condition to read.
The contract belongs to the public root agent alone. A local child agent does not inherit it, and neither does an agent tool. If a child template is compiled and invoked as a root agent in its own right, its own schema applies to that separate revision.
There is no text fallback. A provider refusal, an incomplete generation, invalid JSON, or a validation failure fails the Task. The invalid output is not published and is not included in the error, because it may carry sensitive data, so the failure message alone will not show a reader what the model actually returned.
The response arrives as data, not text. The runtime suppresses partial root-answer fragments, validates the complete value, and publishes one A2A DataPart with media type application/json, carrying the canonical schema digest in kagent.dev/a2a/output-schema-sha256. The generated Agent Card advertises application/json as its default output mode. A streaming client that wants only the answer reads the last content-bearing artifact before the Task reaches TASK_STATE_COMPLETED.
Progress updates, tool events, approval requests and input-required messages are unchanged. Structured output constrains the terminal answer, not the conversation around it.
Tool calls work alongside it across OpenAI, Anthropic, Bedrock and Gemini. A provider or model can still refuse structured output at request time even though the schema compiled, and that failure fails the Task.
Where the file goes
docs-site/content/kagent/1.x/agents/structured-output.md sits with the other AgentTemplate behavior pages, alongside system-prompts.md. Placement is the one open question in this issue. The feature is a property of the portable template rather than of the runtime, which argues for agents/, but the harness restriction and the A2A response contract both pull toward the runtime pages. Decide before writing, and say which argument won.
What to check before starting
Read docs/architecture/structured-output.md in the kagent repository.
Read agents/system-prompts.md, which documents the closest existing pattern: an inline field and a ConfigMap-backed alternative on the same spec, including its error table.
Confirm the limits and the profile against go/core/internal/translator/outputschema.go on the version you are documenting.
Run an agent with a schema on a cluster, and run one that violates it, so that the failure behavior on the page is observed rather than inferred.
Done when
The page states that the schema is resolved and validated at compile time, and that an invalid schema stops an agent from running.
The field table covers outputSchema and outputSchemaFrom, and the mutual exclusion is stated with its CEL message.
The portable profile is described, including what it rejects and the three limits.
The harness restriction is stated, and was verified by pairing a schema with a claude or codex Harness on a cluster.
An error table maps each failure to the condition and reason it sets, distinguishing Compatible from ResolvedRefs.
The A2A response contract is documented, including the DataPart, the media type, the digest metadata key, and the absence of a text fallback.
The root-agent scope is stated, so a reader does not expect a child agent to inherit the schema.
Both examples on the page were run against a live agent.
An AgentTemplate can now constrain its answer to a JSON Schema, and the 1.x doc set does not mention the feature anywhere. kagent#2890 landed the CRD fields, the translator, the runtime validation, the A2A response contract, the CLI, and the UI, so a reader can configure structured output today with nothing in the docs to tell them how.
This is new writing rather than an edit.
What the page covers
Declaring a JSON Schema for an agent's successful terminal response, and what the runtime does with a response that does not match.
The spine of the page is that the schema is a compile-time contract, not a request-time hint. The translator resolves the schema, validates it against a portable profile, and records a canonical form and digest in the immutable prepared revision. A schema the profile rejects fails compilation, so no agent runs at all, rather than failing later at inference. Lead with that and the admission rules below stop looking like a list of restrictions and start looking like one decision.
Upstream wrote the design document first.
docs/architecture/structured-output.mdis unusually complete and is the right starting point. It is an architecture document rather than a task guide, so it is a source, not a draft.The configuration surface
Two mutually exclusive fields on
AgentTemplateSpec, defined ingo/api/v1alpha3/agenttemplate_types.go. Omitting both leaves the response unconstrained.outputSchemaoutputSchemaFromnameandkeyselecting a same-namespace ConfigMap that holds the schema as JSON.Admission rules.
outputSchema and outputSchemaFrom are mutually exclusive.properties,required,additionalProperties,items,enum,const,anyOf, titles and descriptions, and non-recursive local references through$defs. External references, recursive references, conditional schemas and tuple arrays are rejected at compile time rather than silently weakened for a provider.$defscount toward both bounds.kagentHarness supports structured output. Thecodex,claudeandbyoHarnesses fail compilation withHarness "<name>" does not support structured output.Behavior the API does not announce
Compatiblecondition toFalsewith the reasonUnsupportedConfiguration. A ConfigMap that does not exist, or a key that is missing from it, setsResolvedRefstoFalsewith the reasonReferenceResolutionFailed. A reader debugging a template needs to know which condition to read.DataPartwith media typeapplication/json, carrying the canonical schema digest inkagent.dev/a2a/output-schema-sha256. The generated Agent Card advertisesapplication/jsonas its default output mode. A streaming client that wants only the answer reads the last content-bearing artifact before the Task reachesTASK_STATE_COMPLETED.Where the file goes
docs-site/content/kagent/1.x/agents/structured-output.mdsits with the other AgentTemplate behavior pages, alongsidesystem-prompts.md. Placement is the one open question in this issue. The feature is a property of the portable template rather than of the runtime, which argues foragents/, but the harness restriction and the A2A response contract both pull toward the runtime pages. Decide before writing, and say which argument won.What to check before starting
docs/architecture/structured-output.mdin the kagent repository.agents/system-prompts.md, which documents the closest existing pattern: an inline field and a ConfigMap-backed alternative on the same spec, including its error table.go/core/internal/translator/outputschema.goon the version you are documenting.Done when
outputSchemaandoutputSchemaFrom, and the mutual exclusion is stated with its CEL message.claudeorcodexHarness on a cluster.CompatiblefromResolvedRefs.DataPart, the media type, the digest metadata key, and the absence of a text fallback.