Message And Artifact Format Requirements¶
Status: proposed requirements for standardizing the multi-agent wire contract.
This document is based on the current implementation, on MESSAGE_SCHEMAS.md, and on the current A2A protocol model. It is intentionally stricter than the code as it exists today.
Its main design decision is:
- Prometheus should use native A2A message and artifact primitives on the wire
- Prometheus-specific behavior should be limited to conversation cataloging, persistence, and UI conventions layered on top of A2A
This document therefore does not define a replacement artifact transport. It defines:
- canonical message usage on top of A2A
- canonical artifact usage on top of A2A
- Prometheus-specific conventions needed for conversation-scoped artifact reuse and frontend visualization
1. Goals¶
The message and artifact contract must:
- provide one canonical location for final structured responses
- use native A2A
ArtifactandPartobjects as the wire format - support both URI-backed artifacts and inline structured JSON artifacts
- allow the frontend to choose renderers by explicit type identifiers rather than by tags or filename heuristics
- separate conversational messages, progress status, and artifact payloads cleanly
2. Non-goals¶
This document does not require:
- backward compatibility with older payload aliases
- arbitrary inline binary blob conventions beyond what A2A already supports
- dependence on
metadata.type,metadata.content,metadata.data, tag-only routing, or URI-extension routing for new producers - a Prometheus-specific artifact wire schema separate from A2A
3. Core Principles¶
3.1 Use A2A natively¶
Prometheus must treat A2A as the wire-level source of truth for:
- request envelopes
- response envelopes
- artifact transport
Prometheus-specific requirements should only cover:
- how A2A artifacts are interpreted
- how they are persisted across turns
- how the frontend chooses renderers
3.2 Canonical response location¶
Final structured message responses must live in:
result.status.message.parts[*].text
That text payload must contain one serialized JSON object representing the response envelope.
result.artifacts is for artifacts only. It must not be used as an alternate location for the primary response envelope.
result.history is diagnostic only. Clients must not depend on it for normal result extraction.
3.3 Explicit typing over inference¶
Artifact rendering and downstream consumption must be driven by:
- explicit MIME metadata on the primary A2A part
- Prometheus
json_typefor JSON parts
In the currently installed Python A2A library, that means:
- URI-backed artifacts use
kind: "file"andfile.mimeType - inline structured artifacts use
kind: "data"and partmetadata.mime_type
Tags, URI extensions, and arbitrary metadata must not be required for correct routing of conforming artifacts.
4. Message Requirements¶
4.1 A2A request envelope¶
The platform must use message/send for synchronous agent invocation.
The inner request payload in params.message.parts[0].text must be a serialized JSON object.
Required request envelope fields:
{
"jsonrpc": "2.0",
"id": "<request_id>",
"method": "message/send",
"params": {
"message": {
"messageId": "<message_id>",
"role": "user",
"parts": [
{
"type": "text",
"text": "{...json object...}"
}
]
},
"configuration": {
"blocking": true
},
"context": {
"conversationId": "<conversation_id>",
"skillId": "<skill_id>"
}
}
}
Requirements:
params.message.partsmust contain exactly one text part for structured requests.- The text content must be valid JSON.
context.conversationIdmust always be present.context.skillIdmust be present for specialist-agent invocations and may be omitted only for top-level orchestrator chat endpoints that perform their own routing.
4.2 Final response envelope¶
The canonical final response object for conversation-facing flows must be:
{
"conversation_id": "<uuid>",
"status": "needs_info|plan_ready|executing|completed|recommendation|answer|error",
"message": "..."
}
Additional fields by status:
needs_info:followup_questionsplan_ready:plancompleted:report,tool_resultsrecommendation|answer:response_text, optionalrecommended_materials
Cross-cutting optional fields:
artifacts: full conversation artifact catalog after this turnnew_artifacts: the artifacts this turn producedmessage_metadata: UI-facing metadata such as follow-up suggestions
Requirements:
- the response envelope must appear only in
result.status.message.parts[*].text result.artifactsmust carry artifacts, not duplicate conversation responsesartifactsmust be the post-turn full catalognew_artifactsmust hold only what the current turn produced: the artifacts its own dispatches returned, its uploads, and any artifact its response brings into the catalog. It is not a diff of the catalog. A turn running in the background registers into the same catalog, so a diff would pick up its artifacts.
4.3 Status updates¶
Status updates are separate from final responses.
Requirements:
- progress status updates must use
result.status.state = "working" - final success must use
result.status.state = "completed" - final failure must use
result.status.state = "failed" - status messages should be human-readable text, not artifact payloads
- status updates must not be the only location of durable structured results unless they carry the final canonical response envelope
5. Artifact Requirements¶
5.1 Native A2A artifact is the wire format¶
Prometheus must use native A2A Artifact objects on the wire.
A Prometheus-conforming artifact should look like:
{
"artifactId": "<artifact_id>",
"name": "Corrosion Summary",
"description": "Summarized corrosion analysis output for Alloy 600",
"parts": [
{
"kind": "data",
"data": {
"material_id": "Alloy 600",
"findings": ["..."]
},
"metadata": {
"mime_type": "application/json",
"json_type": "prometheus.analysis.corrosion_summary.v1"
}
}
],
"metadata": {
"conversation_id": "<conversation_id>",
"producer_agent_id": "corrosion-agent",
"tags": ["analysis", "corrosion"],
"created_at": "2026-03-18T00:00:00+00:00"
}
}
Requirements:
- Prometheus must not define a separate artifact transport format in parallel with A2A
- artifact content must be carried using A2A
Partvariants - Prometheus-specific fields must live in metadata conventions, not in a competing wire schema
5.2 URI-backed artifacts¶
URI-backed artifacts must use an A2A file part.
Example:
{
"artifactId": "<artifact_id>",
"name": "Generated Report",
"description": "PDF report for the corrosion run",
"parts": [
{
"kind": "file",
"file": {
"uri": "file:///tmp/report.pdf",
"mimeType": "application/pdf",
"name": "report.pdf"
}
}
],
"metadata": {
"conversation_id": "<conversation_id>",
"producer_agent_id": "corrosion-agent",
"created_at": "2026-03-18T00:00:00+00:00"
}
}
Requirements:
- URI-backed artifacts are the canonical representation for files and external resources
- the file part
file.urimust be the authoritative locator for the content - the file part
file.mimeTypemust reflect the content actually available at that URI
5.3 Inline JSON artifacts¶
The system must support inline structured data using an A2A data part.
Example:
{
"artifactId": "<artifact_id>",
"name": "Trace Matrix",
"description": "Requirements traceability matrix",
"parts": [
{
"kind": "data",
"data": {
"rows": []
},
"metadata": {
"mime_type": "application/json",
"json_type": "prometheus.requirements.trace_matrix.v1"
}
}
],
"metadata": {
"conversation_id": "<conversation_id>",
"producer_agent_id": "requirements-agent",
"created_at": "2026-03-18T00:00:00+00:00"
}
}
Requirements:
- inline generic structured data must use an A2A data part, not a text-encoded JSON blob
- JSON parts must carry
metadata.mime_type = "application/json" - JSON parts must include
metadata.json_type json_typemust be stable, explicit, and versioned- the frontend must use
json_typeto choose a specialized renderer when one exists - when no specialized renderer exists, the frontend must fall back to a generic JSON viewer
Recommended json_type naming pattern:
- lowercase dotted identifier with an explicit version suffix
- example:
prometheus.analysis.corrosion_summary.v1 - example:
prometheus.requirements.trace_matrix.v1 - example:
prometheus.workflow.execution_trace.v1
5.4 Prometheus conversation catalog¶
Prometheus still needs a conversation-scoped artifact catalog, but that catalog must be treated as a derived projection of A2A artifacts, not a separate wire format.
The catalog may expose normalized fields such as:
artifact_idconversation_idnamedescriptionmime_typejson_typeuriproducer_agent_idcreated_attags
Requirements:
- the catalog entry must be derived from the native A2A artifact
- the catalog exists for persistence, lookup, and UI state across turns
- the catalog must not become an alternate wire format between agents
5.5 Required Prometheus metadata conventions¶
The following metadata conventions are required on Prometheus-produced artifacts:
Artifact-level metadata:
conversation_idproducer_agent_idcreated_at
Optional artifact-level metadata:
tags
Part-level metadata for JSON parts:
json_type
Requirements:
conversation_idis required because A2A artifact identity is task-scoped, while Prometheus needs conversation-scoped persistenceproducer_agent_idis required for provenancecreated_atis required for ordering, catalog hydration, and TTL managementjson_typeis required for JSON visualization routing
5.6 Prohibited legacy dependency fields¶
New producers must not rely on any of the following for core semantics:
- top-level
content metadata.contentmetadata.datametadata.type- tag-only viewer routing
- URI-extension-only viewer routing
Those fields may still exist during migration, but they must not be required for correct interpretation of a conforming artifact.
6. Artifact Event Requirements¶
When an artifact is emitted in an A2A artifact slot, the payload itself must already be the native A2A artifact. Prometheus should not require an extra wrapper such as:
{
"artifact": { "...custom object..." }
}
Requirements:
result.artifacts[*]should each contain one native A2A artifact- Prometheus ingestion should normalize from native A2A artifacts directly
- Prometheus should not require a second custom artifact wrapper for conforming producers
7. Frontend Rendering Requirements¶
The frontend renderer must dispatch in this order:
- explicit MIME metadata on the primary part
metadata.json_typefor JSON parts
Requirements:
- media type is the primary renderer key
json_typeis the subtype key for JSON artifacts- tags may be used for display or search, not as the primary rendering contract
- URI extensions may be used only as a temporary migration fallback, not as the required long-term contract
Expected behaviors:
application/pdf-> PDF viewer- canonical IFC media type adopted by the platform -> IFC viewer
- canonical Exodus media type adopted by the platform -> Exodus viewer
text/mermaid-> Mermaid viewerapplication/json+ knownjson_type-> specialized JSON viewerapplication/json+ unknownjson_type-> generic JSON viewer
8. Validation Requirements¶
Artifact validation must enforce:
- every Prometheus artifact is a valid native A2A artifact
- every artifact has exactly one primary part for current Prometheus usage
- every primary part has explicit MIME metadata
- JSON parts use
metadata.mime_type = "application/json" - JSON parts include
metadata.json_type - Prometheus metadata includes
conversation_id,producer_agent_id, andcreated_at
Message validation must enforce:
- A2A request body is valid JSON
- final structured responses appear only in the canonical response location
- artifact payloads are not overloaded as alternate response envelopes
9. Migration Guidance¶
The current codebase still contains fallback-oriented behavior:
- layered A2A response extraction across status, artifacts, and history
- artifact rendering by MIME type, tags, URI extension, and metadata conventions
- ad hoc inline content paths for some plugins
- compatibility parsing for older text-encoded artifact payloads
Migration should converge on this order:
- standardize the canonical response location
- emit native A2A artifacts directly
- map URI-backed outputs to A2A file parts
- map inline structured JSON outputs to A2A data parts
- add required Prometheus metadata conventions
- update frontend rendering to use media type then
json_type - remove producer reliance on metadata- and extension-based routing
10. Summary¶
The required long-term contract is:
- one canonical response envelope location
- native A2A artifacts as the only wire-level artifact format
- Prometheus metadata conventions layered on top for conversation scope and UI routing
- explicit media-type-driven rendering
- explicit
json_typerouting for JSON artifacts - support for both URI-backed and inline JSON artifacts without inventing a parallel artifact transport