Skip to content

RFC: should Asset cover inbound user-supplied files (content access, media type, durability)? #1875

Description

@jasperblues

Question

Should Asset grow content access, a media type, and a durability mechanism — so that user-supplied inbound files are first-class in a Conversation — or is that deliberately out of scope for the shared interface?

Raising as an RFC rather than a PR, because the answer determines whether downstream implementations should be extending Asset or building alongside it, and it would be better to settle that once than to have several implementations diverge.

What exists today

Asset : LlmReferenceProvider, StableIdentified, Timestamped, with a persistent() flag. Conversation : AssetView derives assets from its assetTracker plus any message implementing AssetView, deduplicated by id, tracker taking priority.

So an asset is defined by being referenceable by the LLM, and the model is derived — assets come from messages.

Where it doesn't reach

Building a chat surface that accepts arbitrary user-uploaded files (images, PDFs, CSVs, data exports), four gaps showed up. Each is arguably by design; that's the question.

  1. No content access. An Asset yields an LLM reference. There is no way for a non-LLM consumer to obtain the bytes. Anything that must inspect content — sniff a format, parse a table, checksum a file — cannot work through the interface.

  2. No media type, size, or content hash. Nothing to route on, nothing to bound cost with, nothing to recognise a re-upload of identical content by.

  3. persistent() is declared, but no persistence mechanism exists. The interface anticipates that an asset might be durable and leaves the how open. Reasonable, but it means "this asset is persistent" is currently unfalsifiable from inside the interface.

  4. Direction of travel is outbound. Assets are derived from messages — things already produced and already understood. A user upload is inbound: it arrives before anything knows what it is, and may never be understood at all. AssetView has no way to represent "present, stored, intent unresolved".

Options

A. Leave Asset as-is. It stays the LLM-facing abstraction. Storage, media types and durability belong to whatever persistence layer an application already has, and an inbound file surfaces as an Asset once it is understood well enough to be referenced. Downstream builds alongside, and nothing in the shared interface obliges an in-memory Conversation to answer questions it structurally cannot.

B. Widen Asset. Add optional content access and media-type metadata, and define what persistent() actually promises. More capable out of the box, at the cost of every implementation — including purely in-memory ones with nowhere to put bytes — having to answer for them.

C. A sibling abstraction. Leave Asset alone and introduce something inbound-shaped next to it, with Asset remaining the projection once an inbound file becomes referenceable.

Our own reading leans towards A, on the grounds that the current shape looks deliberate rather than incomplete — persistent() existing with no mechanism reads as an intentional seam. But that is a guess about intent, which is exactly what this issue is asking.

What would help

Mainly: was the outbound, LLM-facing framing a deliberate boundary? If so it would be worth saying so in the KDoc, since the natural first instinct on encountering Asset is to reach for it to model uploads, and discovering the gap takes a while.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions