refactor(core): resolve attachments durably at promotion

This commit is contained in:
Kit Langton 2026-07-02 09:48:02 -04:00
commit 994f55423a
14 changed files with 252 additions and 252 deletions

View file

@ -105,10 +105,24 @@ export const Forked = Event.define({
})
export type Forked = typeof Forked.Type
/**
* Model-visible content captured for one attachment URI at promotion time:
* a data URL for media, otherwise text. Recorded on the event so projection
* replay stays deterministic without filesystem access.
*/
export const AttachmentResolution = Schema.Struct({
uri: Schema.String,
resolved: Schema.String,
}).annotate({ identifier: "session.next.event.attachment-resolution" })
export interface AttachmentResolution extends Schema.Schema.Type<typeof AttachmentResolution> {}
export const Prompted = Event.define({
type: "session.next.prompted",
...options,
schema: PromptFields,
schema: {
...PromptFields,
resolutions: Schema.Array(AttachmentResolution).pipe(optional),
},
})
export type Prompted = typeof Prompted.Type

View file

@ -41,11 +41,22 @@ export const ModelSwitched = Schema.Struct({
model: Model.Ref,
}).annotate({ identifier: "Session.Message.ModelSwitched" })
/**
* A prompt attachment plus the model-visible content captured for it at
* promotion time: a data URL for media, otherwise text. The original `uri`
* and `mime` are preserved for provenance; only `resolved` is server-produced.
*/
export interface UserFile extends Schema.Schema.Type<typeof UserFile> {}
export const UserFile = Schema.Struct({
...FileAttachment.fields,
resolved: Schema.String.pipe(optional),
}).annotate({ identifier: "Session.Message.UserFile" })
export interface User extends Schema.Schema.Type<typeof User> {}
export const User = Schema.Struct({
...Base,
text: Prompt.fields.text,
files: Prompt.fields.files,
files: Schema.Array(UserFile).pipe(optional),
agents: Prompt.fields.agents,
type: Schema.Literal("user"),
}).annotate({ identifier: "Session.Message.User" })