Skip to content

gen-ai: add optional byte_size to multimodal content parts#143

Open
Mandark-droid wants to merge 1 commit into
open-telemetry:mainfrom
Mandark-droid:gen-ai/multimodal-byte-size
Open

gen-ai: add optional byte_size to multimodal content parts#143
Mandark-droid wants to merge 1 commit into
open-telemetry:mainfrom
Mandark-droid:gen-ai/multimodal-byte-size

Conversation

@Mandark-droid

@Mandark-droid Mandark-droid commented May 11, 2026

Copy link
Copy Markdown
Contributor

Description

Adds an optional byte_size field on BlobPart, FilePart, and UriPart in the gen-ai input, output, and system-instructions message JSON schemas. byte_size captures the size, in bytes, of the captured or referenced media payload as observed by the instrumentation at the time of capture.

Concretely each part type carries its own focused description:

Part byte_size description
BlobPart Size of the captured payload in bytes — the raw decoded byte length, not the length of the base64-encoded content string on the wire.
FilePart Size of the referenced file in bytes, as observed by the instrumentation at capture time.
UriPart Size of the URI-referenced payload in bytes, as observed by the instrumentation at capture time.

The Pydantic source models in docs/gen-ai/non-normative/models.ipynb declare byte_size: Optional[int] = Field(default=None, ge=0, ...) so the regenerated JSON schemas carry "minimum": 0 inside the anyOf integer branch — negative values are rejected by validators rather than silently accepted.

Follow-up from the closed PR open-telemetry/semantic-conventions#3673 (split into three small PRs per the new repo's "keep PRs small" guidance: this one, the document modality PR #142, and the stripped_reason PR #144). The three are independent and additive.

Motivation

User journey: cost-of-capture telemetry, storage planning, and capacity forecasting for content-capturing instrumentation.

A single logical multimodal request may be carried inline (BlobPart with base64 content), by URI (UriPart pointing at S3 / GCS / MinIO / similar), or by provider-side file id (FilePart). Without a uniform byte_size, an operator who wants to answer "how much media data are we ingesting per minute / per tenant / per modality?" has to:

  • For BlobPart: base64-decode content and count bytes (and decide whether to do that per-span, which is expensive).
  • For UriPart: dereference the URI to a backing store and HEAD it (involves an extra request and trust in the store).
  • For FilePart: ask the provider's files API for size metadata (extra API call, rate-limited, provider-specific).

Putting an optional byte_size directly on the captured part lets the producing instrumentation record what it already knows (it just saw the bytes or just got back a content-length header / file metadata) so consumers don't have to re-derive it later.

Prior art:

  • AWS X-Ray / Bedrock spans record request and response sizes as flat attributes.
  • OpenAI's Files API exposes bytes on every file object — instrumentation that's about to upload via Files.create() already has this number.
  • The reference implementation in genai-otel-instrument (v1.1.1) already populates an equivalent inside its dual-emission JSON when OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai — this PR upstreams the convention.

Prototype

This PR ships the schema change in docs/gen-ai/. The repo's reference scenarios under reference/scenarios/<library>/ are all currently text-only — none emit BlobPart/FilePart/UriPart today — so there is no obvious existing scenario to add byte_size to without first introducing a multimodal scenario.

I flagged this as an open question in the original PR body (and on the closed-and-refiled open-telemetry/semantic-conventions#3673): would maintainers prefer (a) extending an existing <library> scenario (e.g. openai) with a multimodal call that emits byte_size, or (b) a dedicated openai-multimodal (or similar) scenario, given the SDK call shape changes? Happy to do either as a follow-up — leaving this checkbox unchecked rather than guessing the shape. Cross-referenced from #142, where the document-modality counterpart of this question was raised and approved without a scenario.

End-to-end producer verification: the genai-otel-instrument library emits byte_size on URI parts captured by its OpenAI / Anthropic / Bedrock instrumentors, validated through an OTel collector → OpenSearch pipeline against a MinIO-backed media store; the actual size value observed at capture time round-trips into the gen_ai.input.messages span attribute as the JSON schema in this PR describes.

Checklist

  • Motivation section filled in above
  • Reference scenarios updated for affected libraries — deferred pending maintainer guidance on shape; see Prototype section
  • Changelog entry added under Unreleased in CHANGELOG.md

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds an optional byte_size field to GenAI multimodal content part schemas to consistently report payload size across inline blobs, provider file IDs, and URIs.

Changes:

  • Add byte_size: Optional[int] to BlobPart, FilePart, and UriPart non-normative models and regenerate the normative JSON schemas.
  • Update a multimodal example to include byte_size.
  • Document the enhancement in CHANGELOG.md.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
docs/gen-ai/non-normative/models.ipynb Adds byte_size to the reference (non-normative) Pydantic models for three part types.
docs/gen-ai/non-normative/examples-llm-calls.md Demonstrates byte_size usage in a multimodal URI example.
docs/gen-ai/gen-ai-system-instructions.json Regenerated schema including optional byte_size on relevant part definitions.
docs/gen-ai/gen-ai-output-messages.json Regenerated schema including optional byte_size on relevant part definitions.
docs/gen-ai/gen-ai-input-messages.json Regenerated schema including optional byte_size on relevant part definitions.
CHANGELOG.md Records the new optional field under Unreleased enhancements.

Comment thread docs/gen-ai/non-normative/models.ipynb Outdated
Comment thread docs/gen-ai/non-normative/models.ipynb Outdated
Comment thread docs/gen-ai/non-normative/models.ipynb Outdated
Comment thread docs/gen-ai/gen-ai-input-messages.json Outdated
Comment thread docs/gen-ai/non-normative/examples-llm-calls.md Outdated
Comment thread CHANGELOG.md Outdated
@Mandark-droid

Copy link
Copy Markdown
Contributor Author

Thanks @Copilot for the review — all four items addressed in b6930e0:

  • byte_size >= 0 — added Pydantic ge=0 on the byte_size field of BlobPart/FilePart/UriPart in models.ipynb. The regenerated JSON schemas now emit "minimum": 0 inside the anyOf integer branch, so consumers get consistent validation rather than silently accepting negative values. This is exactly the "via a Pydantic constraint such as ge=0" path you suggested.
  • byte_size description for BlobPart — clarified that for BlobPart, byte_size is the size of the raw payload (the decoded byte length), not the length of the base64-encoded content string on the wire. The same description now reads identically on FilePart and UriPart since the on-wire payload there is opaque (no base64 ambiguity), keeping the field semantics uniform across the three parts.
  • "vendor specific" → "vendor-specific" — hyphenated the compound modifier in the example.
  • "file id" → "file ID" — capitalized in the CHANGELOG entry.

make check-policies and make generate-all re-validated locally on the updated branch.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Comment thread docs/gen-ai/non-normative/models.ipynb Outdated
Comment thread docs/gen-ai/non-normative/models.ipynb Outdated
Comment thread docs/gen-ai/gen-ai-input-messages.json Outdated
Comment thread docs/gen-ai/gen-ai-output-messages.json Outdated
Comment thread docs/gen-ai/gen-ai-system-instructions.json Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment thread CHANGELOG.md Outdated
Comment on lines +13 to +16
- Add optional `byte_size` field on `BlobPart`, `FilePart`, and `UriPart` in the GenAI
input/output/system-instructions message JSON schemas. Captures the size of the payload (in
bytes) at the point of capture, useful for cost-of-capture telemetry and storage planning when
the same logical request might be carried inline, by URI, or by provider file ID.
@trask

trask commented May 11, 2026

Copy link
Copy Markdown
Member

@Mandark-droid

Copy link
Copy Markdown
Contributor Author

Thanks @Copilot for the second pass — good catch. Addressed in d725a44:

In the first fixup I broadened the description to mention BlobPart-specific base64 semantics, but applied it uniformly across all three parts. That was wrong: FilePart and UriPart have no content field so the base64 caveat doesn't apply there. Now each part has its own focused description:

Part Description
BlobPart Size of the captured payload in bytes — the raw decoded byte length, not the length of the base64-encoded content string on the wire.
FilePart Size of the referenced file in bytes, as observed by the instrumentation at capture time.
UriPart Size of the URI-referenced payload in bytes, as observed by the instrumentation at capture time.

The notebook and the three generated JSON schemas are updated in lockstep; make check-policies and make generate-all re-validated locally.

@Mandark-droid

Copy link
Copy Markdown
Contributor Author

@trask done — PR body now filled out against the new template. Description / Motivation (with user journey + prior art) / Prototype / Checklist all in place.

One checklist item left intentionally unchecked: Reference scenarios updated for affected libraries. I flagged this in the Prototype section — the repo's existing reference/scenarios/<library>/ scenarios are all text-only today, so there's no obvious existing scenario to extend with a byte_size-bearing BlobPart/FilePart/UriPart. Same situation on the sister PRs #142 and #144. Two paths and I'd like your call before I do the work:

  1. Extend an existing library scenario (most likely openai) with a small multimodal call — would change the SDK invocation shape there (vision input / file id input), so the scenario stops being "minimal text-only" but stays under the existing library directory.
  2. Add a dedicated openai-multimodal/ (or multimodal/) scenario that lives alongside the others — keeps the existing scenarios untouched, but adds a whole new uv-locked scenario folder + data.json + README regen.

If you prefer (1) or (2), I'll do it as part of this PR. If you'd rather land the schema changes first and follow up with the multimodal scenario(s) as a separate PR — also happy to do that, especially since the same scenario will want to exercise document modality (#142), byte_size (#143), and stripped_reason (#144) together rather than in three separate scenario additions.

Also note PR #142 was already approved by @MikeGoldsmith on a deferred-scenario basis — if the same standard applies here #143 and #144 could land first and the scenario lands in a unified follow-up. Whatever you prefer.

PR #144's body has been similarly filled out against the template; @MikeGoldsmith, flagging since you reviewed #142.

@trask

trask commented May 11, 2026

Copy link
Copy Markdown
Member

let's add the scenario to #142, get that merged, then you can update that scenario in this PR

Mandark-droid added a commit to Mandark-droid/semantic-conventions-genai that referenced this pull request May 12, 2026
Per @trask's direction on PR open-telemetry#143, the multimodal scenario lives in
open-telemetry#142 so it can carry the document modality first, then be extended
in open-telemetry#143 (byte_size) and open-telemetry#144 (stripped_reason) once this lands.

Adds run_chat_with_document_input_reference(client) to the openai
scenario, exercising the new 'document' enum value on a UriPart in
gen_ai.input.messages. The OpenAI SDK call uses the documented file
content block; the canonical OTel attribute carries a TextPart plus a
document-modality UriPart, mirroring how a KYC document-extraction
workload surfaces in the wire shape.
"type": "uri",
"modality": "video",
"mime_type": "video/mp4",
"byte_size": 5242880,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For uri and file type responses, I suspect you may not actually be able to obtain the byte_size value, since it is generally only determined when the content is downloaded.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, and the schema does handle this case — byte_size is Optional[int] precisely so instrumentations omit it when the value isn't cheaply observable. But it's worth saying why we wanted this field in the first place, because it shapes which cases legitimately have a size and which don't.

Motivation: trace-side metadata as a join key for offline multimodal evals.

The field exists to support a pattern we ship in genai-otel-instrument: optional offload of multimodal payloads (images / audio / video / documents) to an object store — MinIO in our default deployment, configurable to any S3-compatible target — while spans carry only lightweight metadata (modality, MIME, byte size, source, SHA, store URI). The bytes themselves never go on the span. The store becomes the substrate for downstream evaluation: LLM-as-judge passes over generated images, voice-quality scoring on audio responses, OCR/grounding checks on document inputs, joint text+image evals on text-to-image flows (judge both the prompt and the produced artifact). As the industry moves toward voice and multimodal use cases this becomes the dominant eval shape, and trace ↔ artifact correlation is what makes it tractable.

byte_size plays two roles in that pattern:

  1. Standalone signal when the offload sink is off. Even with no object store wired up, byte size on the span gives operators a meaningful low-cost dimension — cost attribution (multimodal billing scales with payload size), spotting oversized or empty inputs, anomaly detection. It's a single integer; negligible on the wire.
  2. Correlation / integrity key when the sink is on. Pairs with mime_type + (optionally) sha256 to let an evaluator join the lightweight trace to the heavyweight artifact in the store, and to detect truncation/corruption between span emission and storage.

Which UriPart / FilePart cases actually have a known size — concretely, in our reference impl:

There are three code paths that produce a UriPart-shape, and byte_size is set on two of them:

  1. Inline bytes → uploaded to object store → UriPart (media/offload.py:142-147). We started with inline data: URIs or raw bytes from the SDK, computed len(payload), uploaded, and emit a UriPart pointing at the upload. Size is exact because we held the bytes. This is the primary "interesting" case — it's also the case where byte_size is most load-bearing for evals, because it lets the evaluator verify the artifact in the store matches what the trace says was sent.
  2. Inline bytes too large to upload → stripped UriPart-shape (media/offload.py:114-120). We set media_byte_size = len(part.data) before dropping the buffer, then emit a stripped part with stripped_reason: "size_exceeded". Size is the entire reason this branch exists — without it, consumers can't tell why the part was stripped or estimate what was lost.
  3. Caller-supplied external URL → UriPart (media/offload.py:95-99). User passed an already-remote URL (e.g. OpenAI image_url with https://…). We record media_uri = part.external_url and do not set media_byte_size. The canonical writer at media/canonical.py:66-67 only emits byte_size when it's not None, so this UriPart goes out without it — exactly what you'd want.

The same logic applies to FilePart: when an app references a provider-side file (OpenAI Files API returns bytes, Anthropic Files returns size_bytes, Gemini File.sizeBytes), the SDK response carries the size, so it's known without a download. When it isn't carried, the field stays unset.

On the example you flagged (examples-llm-calls.md:245, "vendor-specific URI" video): you're right that as written it implies an instrumentation magicked the size out of a remote URL. In our impl's terms that's the external_url path, where byte_size is not set. I'll push an example fix that drops byte_size from that specific UriPart entry and adds a brief note explaining that byte_size on UriPart is only populated when the instrumentation observed the bytes before they became a URI — typically the offload-to-object-store flow this field is designed to support. Happy to instead replace with an inline-then-offloaded UriPart (where size is genuinely known) plus a sibling URI example without byte_size if you'd prefer the canonical "size on UriPart is legitimate" case demonstrated explicitly. LMK.

Mandark-droid added a commit to Mandark-droid/semantic-conventions-genai that referenced this pull request May 15, 2026
Address review feedback on PR open-telemetry#143: a pre-existing remote URI's size
generally is not observable to instrumentation without downloading the
content, so the vendor-specific URI example should not carry byte_size.
Set byte_size on a uri part only when bytes were observed before they
became a URI (e.g. inline payload uploaded to an object store). Also
add byte_size to the inline blob image example where the value is
unambiguous.
github-merge-queue Bot pushed a commit that referenced this pull request May 16, 2026
* gen-ai: add document modality to multimodal content parts

Adds the 'document' value to the Modality enum in the gen-ai input,
output, and system-instructions message JSON schemas. Today PDF/DOCX
and similar parts have to fall through to the free-form string branch
of the modality anyOf; this change gives them a first-class enum value
matching the existing image/video/audio entries.

Pure addition: no removals, no changes to required fields. The notebook
source under docs/gen-ai/non-normative/models.ipynb has been updated to
keep the regen-from-notebook flow consistent, and a worked example was
added to examples-llm-calls.md.

Follow-up from open-telemetry/semantic-conventions#3673 (closed and
refiled here per the new repo home for gen-ai semantic conventions).

* gen-ai: add document-modality reference scenario to openai

Per @trask's direction on PR #143, the multimodal scenario lives in
#142 so it can carry the document modality first, then be extended
in #143 (byte_size) and #144 (stripped_reason) once this lands.

Adds run_chat_with_document_input_reference(client) to the openai
scenario, exercising the new 'document' enum value on a UriPart in
gen_ai.input.messages. The OpenAI SDK call uses the documented file
content block; the canonical OTel attribute carries a TextPart plus a
document-modality UriPart, mirroring how a KYC document-extraction
workload surfaces in the wire shape.

* gen-ai: apply ruff format to multimodal scenario block

* gen-ai: address scenario-evaluation feedback on PR #142

@trask's reference-scenario SKILL evaluation flagged that the previous
openai multimodal block fabricated a URI and mime_type that aren't on
the chat.completions.create boundary -- file_id is opaque, neither
yields a public URI or mime type without a separate Files-API roundtrip.

Two fixes per the evaluation:

1. Rewrite the openai scenario to use the inline file_data shape
   ({'type': 'file', 'file': {'file_data': 'data:application/pdf;base64,...',
   'filename': '...'}}) and emit a BlobPart instead of a UriPart. Every
   emitted BlobPart field now derives directly from the SDK arg:
     - mime_type from the data-URI prefix
     - content from the base64 portion
     - modality 'document' from the classification of application/pdf
   No fabricated URIs.

2. Add run_chat_with_document_input() to the anthropic scenario.
   Anthropic's Messages API has a first-class document content block
   ({'type': 'document', 'source': {'type': 'base64',
   'media_type': '...', 'data': '...'}}), so the BlobPart emission is
   directly observable from the SDK call boundary with no derivation
   gymnastics.

Both scenarios run cleanly against the local mock server; weaver
live-check reports no after_resolution policy violations on either.
The bedrock-converse demonstration trask also suggested is deferred to
a follow-up (DocumentBlock has the same shape; happy to add if needed).

Addresses #142 (comment)...

* gen-ai: add Bedrock Converse DocumentBlock reference + ruff import-sort fix

Completes @trask's three-scenario request for PR #142:

- openai: inline file_data + BlobPart (previous commit, derives mime/content/modality from SDK arg)
- anthropic: native document content block + BlobPart (previous commit)
- aws-bedrock: native Converse DocumentBlock + BlobPart (this commit) -- the
  DocumentBlock 'format' / 'source.bytes' fields map 1:1 to the BlobPart
  mime_type/content with zero out-of-band derivation. Most direct of the three.

Also applies the ruff isort fix from this run (I001 in the anthropic scenario
file: import base64 should sort after import anthropic in the new function
-- ruff check --fix moved it).

All three scenarios validated locally against the mock LLM server; weaver
live-check reports no after_resolution policy violation on any of them.
ruff format + ruff check both clean.

* gen-ai: drop incorrect filename claim from anthropic doc-input docstring

Round-3 Copilot review on PR #142: the docstring claimed Anthropic's
document content block exposes 'mime type, source bytes, and filename'
on the SDK boundary, but the scenario does not include a filename
field in its payload. Removing the filename claim keeps the docstring
accurate to the scenario; if/when a filename field is added to the
schema in a follow-up (per issue #50), the docstring can be updated
alongside.
This was referenced May 26, 2026
"description": "The general modality of the data if it is known. Instrumentations SHOULD also set the mimeType field if the specific type is known.",
"title": "Modality"
},
"byte_size": {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how would instrumentation capture this on FilePart and UriPart?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The answer differs by part:

FilePart — the size comes back in the SDK response, no download needed. When an app references a provider-side file, the file-create / file-get call already returns the size: OpenAI Files bytes, Anthropic Files size_bytes, Gemini File.size_bytes. The instrumentation reads it off the same object it's already inspecting to build the part. When a provider doesn't surface it, the field stays unset (Optional).

UriPart — two sub-cases:

  • Instrumentation-produced URI (the case the field is really for): the instrumentation held the bytes inline, computed len(payload), uploaded them to an object store, and emitted a UriPart pointing at the upload. Size is exact because the bytes were in hand before they became a URI. This is the offload-to-object-store flow byte_size is designed for — it lets an offline evaluator join the lightweight span to the heavyweight artifact and detect truncation.
  • Caller-supplied pre-existing remote URL (e.g. an image_url that's already https://…): the size generally isn't observable without downloading, so byte_size is not set. That's the misleading example you and @Cirilla-zmh flagged; it's corrected in 77d45f8 — the remote-URI example no longer carries byte_size, with a note that it's only populated when the bytes were observed before becoming a URI, and the inline-blob example gains it where the value is unambiguous.

BlobPart — agreed it's derivable from the base64 length, so on its own it's redundant. The reason to still allow it is uniformity across the three part types, and — as you noted — it's the only surviving size signal once #144 lets content be omitted: {"type":"blob","modality":"image","stripped_reason":"size_exceeded","byte_size":2000000} tells a consumer how much was dropped. So byte_size and #144 are complementary by design.

If you'd rather land this narrowly, I can take the same approach as #144 — scope this PR to byte_size on input-messages BlobPart only and replicate to FilePart/UriPart plus the other two schemas in a follow-up.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add reference scenarios for FilePart and UriPart?

"description": "The general modality of the data if it is known. Instrumentations SHOULD also set the mimeType field if the specific type is known.",
"title": "Modality"
},
"byte_size": {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on BlobPart, it's a bit redundant with content since easy to calculate from the base64 length

I think would be ok to capture on BlobPart for consistency with others, but I'm not sure about the others (see other comment), which is why I mention

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, I see, this would be useful with #144 which makes content optional

"video",
"audio"
"audio",
"document"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@Mandark-droid
Mandark-droid force-pushed the gen-ai/multimodal-byte-size branch from 77d45f8 to 8d5a161 Compare June 1, 2026 12:29
@Mandark-droid

Copy link
Copy Markdown
Contributor Author

Rebased onto main now that #142 has landed — the merged document-modality commits drop out, so this is down to a single commit (8d5a161) adding optional byte_size to BlobPart/FilePart/UriPart across the input/output/system-instructions schemas, plus the reference model and examples. The earlier example clarification (remote-URI size is not observable without a download; only set byte_size when the bytes were seen before becoming a URI) is folded into this commit.

Reference-scenario emission is deferred to the follow-up that will carry document-modality, byte_size, and stripped_reason (#144) together in one multimodal scenario.

@trask

trask commented Jun 10, 2026

Copy link
Copy Markdown
Member

Hi! As part of #275, this repository switched to Towncrier changelog fragments to reduce merge conflicts in CHANGELOG.md.

Please move this PR's changelog entry out of CHANGELOG.md and into this Towncrier fragment:

Create changelog.d/143.enhancement.md containing the change log entry, e.g.:

Add optional `byte_size` (non-negative integer) to `BlobPart`, `FilePart`, and `UriPart` in the GenAI input/output/system-instructions message JSON schemas. Lets instrumentations record the size of a captured media payload for cost-of-capture telemetry and storage planning; omitted when the size is not cheaply observable (e.g. a pre-existing remote URI).

After adding the fragment, please remove this PR's direct edit to CHANGELOG.md. Towncrier will add the PR link from the fragment filename when release notes are generated.

Thanks!

Add an optional non-negative byte_size to BlobPart, FilePart, and UriPart
in the gen_ai input/output/system-instructions message JSON schemas. Lets
an instrumentation record the size of a captured media payload for
cost-of-capture telemetry and storage planning. Omitted when the size is
not cheaply observable - e.g. a pre-existing remote URI, where the bytes
would have to be downloaded to measure; set only when the bytes were
observed before becoming a URI. Per-part descriptions reflect this
(decoded byte length for BlobPart, file size for FilePart, payload size
for UriPart). Examples updated accordingly.

Rebased onto main after the Towncrier migration (open-telemetry#275) and the
models.ipynb -> models.py conversion (open-telemetry#226): the field is now declared in
models.py and the committed JSON schemas are regenerated via
make generate-json-schemas; the changelog entry moved from CHANGELOG.md
to changelog.d/143.enhancement.md.
@Mandark-droid
Mandark-droid force-pushed the gen-ai/multimodal-byte-size branch from 8d5a161 to be20d01 Compare June 10, 2026 19:50
@Mandark-droid

Copy link
Copy Markdown
Contributor Author

@trask done — the changelog entry now lives in changelog.d/143.enhancement.md and the direct CHANGELOG.md edit is removed (commit be20d01).

While rebasing onto current main I also ported the PR to the #226 notebook-to-Python conversion: byte_size is now declared on BlobPart/FilePart/UriPart in docs/gen-ai/non-normative/models.py, and the three committed message schemas are regenerated via make generate-json-schemas. The locked generation environment reproduces main's committed output byte-for-byte for untouched schemas, so the JSON diff is unchanged from what was previously reviewed — still just the three byte_size property additions.

@opentelemetry-pr-dashboard

opentelemetry-pr-dashboard Bot commented Jul 18, 2026

Copy link
Copy Markdown

Pull request dashboard status

Status last refreshed: 2026-07-20 23:03:39 UTC.

  • Waiting on: Author
  • Next step: Address or respond to 1 review feedback item:
    • Inline threads: 1
    • For each item, link to the commit that addresses it, explain why no change is needed, or ask a follow-up question.

This automated status or its linked feedback items may be incorrect. If something looks wrong, report it with the result you expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

5 participants