@agentshouse/mdruntime 0.1.0-alpha.20 → 0.1.0-alpha.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/AGENTS.md +9 -1
  2. package/dist/adapter.d.ts +20 -3
  3. package/dist/adapter.d.ts.map +1 -1
  4. package/dist/adapter.js.map +1 -1
  5. package/dist/change-set.d.ts +40 -0
  6. package/dist/change-set.d.ts.map +1 -0
  7. package/dist/change-set.js +94 -0
  8. package/dist/change-set.js.map +1 -0
  9. package/dist/client.d.ts +7 -6
  10. package/dist/client.d.ts.map +1 -1
  11. package/dist/client.js +19 -13
  12. package/dist/client.js.map +1 -1
  13. package/dist/collection.d.ts +8 -2
  14. package/dist/collection.d.ts.map +1 -1
  15. package/dist/collection.js +8 -3
  16. package/dist/collection.js.map +1 -1
  17. package/dist/connection.d.ts +4 -2
  18. package/dist/connection.d.ts.map +1 -1
  19. package/dist/connection.js +308 -168
  20. package/dist/connection.js.map +1 -1
  21. package/dist/conversation.d.ts +28 -16
  22. package/dist/conversation.d.ts.map +1 -1
  23. package/dist/conversation.js +371 -269
  24. package/dist/conversation.js.map +1 -1
  25. package/dist/file.d.ts +2 -2
  26. package/dist/file.d.ts.map +1 -1
  27. package/dist/file.js.map +1 -1
  28. package/dist/host.d.ts.map +1 -1
  29. package/dist/host.js +7 -8
  30. package/dist/host.js.map +1 -1
  31. package/dist/index.d.ts +3 -3
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js.map +1 -1
  34. package/dist/memory.d.ts +3 -2
  35. package/dist/memory.d.ts.map +1 -1
  36. package/dist/memory.js +24 -20
  37. package/dist/memory.js.map +1 -1
  38. package/dist/overlay.d.ts +2 -0
  39. package/dist/overlay.d.ts.map +1 -1
  40. package/dist/overlay.js +106 -0
  41. package/dist/overlay.js.map +1 -1
  42. package/dist/refresh.d.ts.map +1 -1
  43. package/dist/refresh.js +1 -1
  44. package/dist/refresh.js.map +1 -1
  45. package/dist/replica.d.ts +12 -3
  46. package/dist/replica.d.ts.map +1 -1
  47. package/dist/replica.js +61 -26
  48. package/dist/replica.js.map +1 -1
  49. package/dist/store.d.ts +43 -19
  50. package/dist/store.d.ts.map +1 -1
  51. package/dist/store.js +371 -106
  52. package/dist/store.js.map +1 -1
  53. package/dist/wire.d.ts +2 -2
  54. package/dist/wire.d.ts.map +1 -1
  55. package/dist/wire.js +4 -5
  56. package/dist/wire.js.map +1 -1
  57. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdruntime/src/conversation.ts"],"sourcesContent":["import type { QueryDocument, QueryResult } from '@agentshouse/query';\nimport type {\n ConversationAction,\n ConversationCards,\n ConversationEvent,\n ConversationMessage,\n ViewedConversations,\n} from './adapter.js';\nimport { declaredFile, type InstructionFile } from './file.js';\nimport type { CallResult } from './outcome.js';\nimport type { ConversationRecord, InstructionRecord, RuntimeStore } from './store.js';\n\nexport type ConversationEntry = {\n conversation: string;\n card: QueryDocument;\n agent: QueryDocument | null;\n};\n\nexport type GrowingText = { turn: string; text: string };\n\nexport type UnsentInstruction = {\n text: string;\n files: readonly InstructionFile[];\n};\n\nexport type ConversationView = {\n conversation: string;\n messages: readonly ConversationMessage[];\n olderPages: boolean;\n growingText: GrowingText | null;\n summary: unknown;\n instruction: UnsentInstruction | null;\n};\n\nexport type ConversationSurface = {\n list(): Promise<readonly ConversationEntry[]>;\n read(conversation: string): Promise<ConversationView>;\n older(conversation: string): Promise<CallResult | null>;\n compose(conversation: string, instruction: UnsentInstruction): Promise<void>;\n discard(conversation: string): Promise<void>;\n create(input: unknown): Promise<CallResult>;\n send(conversation: string): Promise<CallResult>;\n answer(conversation: string, answer: unknown): Promise<CallResult>;\n interrupt(conversation: string): Promise<CallResult>;\n kill(conversation: string): Promise<CallResult>;\n cancel(conversation: string, turn: string): Promise<CallResult>;\n delete(conversation: string): Promise<CallResult>;\n};\n\nexport type ConversationDependencies = {\n cards(): ConversationCards | undefined;\n documents(): QueryResult;\n call(name: ConversationAction, input: unknown): Promise<CallResult>;\n durably<T>(work: (local: RuntimeStore) => Promise<T>): Promise<T>;\n path(): ViewedConversations | undefined;\n closed(): boolean;\n};\n\nexport type ConversationStore = {\n surface: ConversationSurface;\n hydrate(\n conversations: readonly ConversationRecord[],\n instructions: readonly InstructionRecord[],\n ): void;\n observe(conversation: string, notify: (view: ConversationView) => void): () => void;\n receive(event: ConversationEvent): void;\n close(): void;\n};\n\ntype Held = {\n messages: readonly ConversationMessage[];\n cursor: string | null;\n summary: unknown;\n};\n\ntype Composed = {\n text: string;\n files: readonly InstructionFile[];\n turn: string | null;\n};\n\ntype Viewing = {\n conversation: string;\n notify: (view: ConversationView) => void;\n ready: boolean;\n};\n\ntype HistoryPage = {\n messages: readonly ConversationMessage[];\n cursor: string | null;\n};\n\nconst NO_TURNS: ReadonlySet<string> = new Set();\n\nfunction carriedMessage(value: unknown): ConversationMessage | null {\n if (typeof value !== 'object' || value === null) return null;\n const record = value as { turn?: unknown };\n if (typeof record.turn !== 'string') return null;\n return structuredClone(value) as ConversationMessage;\n}\n\nfunction historyPage(result: CallResult): HistoryPage | null {\n if (result.kind !== 'action') return null;\n const answer = result.result;\n if (typeof answer !== 'object' || answer === null) return null;\n const record = answer as { messages?: unknown; cursor?: unknown };\n if (!Array.isArray(record.messages)) return null;\n const messages: ConversationMessage[] = [];\n for (const entry of record.messages) {\n const carried = carriedMessage(entry);\n if (carried !== null) messages.push(carried);\n }\n return { messages, cursor: typeof record.cursor === 'string' ? record.cursor : null };\n}\n\nfunction turnOf(result: CallResult): string | null {\n if (result.kind !== 'action') return null;\n const answer = result.result;\n if (typeof answer !== 'object' || answer === null) return null;\n const record = answer as { turn?: unknown };\n return typeof record.turn === 'string' ? record.turn : null;\n}\n\nfunction newest(held: Held, page: HistoryPage, arrived: ReadonlySet<string>): Held {\n const arriving = new Set(page.messages.map((entry) => entry.turn));\n const overlap = held.messages.findIndex((entry) => arriving.has(entry.turn));\n const carried = overlap === -1 ? [] : held.messages.slice(0, overlap);\n const placed = new Set([...carried, ...page.messages].map((entry) => entry.turn));\n const live = held.messages.filter((entry) => arrived.has(entry.turn) && !placed.has(entry.turn));\n return {\n ...held,\n messages: [...carried, ...page.messages, ...live],\n cursor: overlap === -1 ? page.cursor : held.cursor,\n };\n}\n\nfunction older(held: Held, page: HistoryPage): Held {\n const present = new Set(held.messages.map((entry) => entry.turn));\n return {\n ...held,\n messages: [...page.messages.filter((entry) => !present.has(entry.turn)), ...held.messages],\n cursor: page.cursor,\n };\n}\n\nfunction sealed(held: Held, arriving: ConversationMessage): Held {\n const at = held.messages.findIndex((entry) => entry.turn === arriving.turn);\n if (at === -1) return { ...held, messages: [...held.messages, arriving] };\n const messages = [...held.messages];\n messages[at] = arriving;\n return { ...held, messages };\n}\n\nexport function createConversationStore(deps: ConversationDependencies): ConversationStore {\n const held = new Map<string, Held>();\n const composed = new Map<string, Composed>();\n const growing = new Map<string, GrowingText>();\n const viewers = new Set<Viewing>();\n const issued = new Map<string, number>();\n const live = new Map<string, Set<string>>();\n let handed: string | undefined;\n\n function heldOf(conversation: string): Held {\n return held.get(conversation) ?? { messages: [], cursor: null, summary: null };\n }\n\n function instructionOf(conversation: string): Composed {\n return composed.get(conversation) ?? { text: '', files: [], turn: null };\n }\n\n function viewOf(conversation: string): ConversationView {\n const carried = heldOf(conversation);\n const unsent = composed.get(conversation);\n return {\n conversation,\n messages: structuredClone(carried.messages),\n olderPages: carried.cursor !== null,\n growingText: growing.get(conversation) ?? null,\n summary: structuredClone(carried.summary),\n instruction:\n unsent === undefined || unsent.turn !== null\n ? null\n : { text: unsent.text, files: [...unsent.files] },\n };\n }\n\n function emit(conversation: string) {\n if (deps.closed()) return;\n for (const viewer of viewers) {\n if (viewer.conversation === conversation && viewer.ready) viewer.notify(viewOf(conversation));\n }\n }\n\n function viewed(): readonly string[] {\n return [...new Set([...viewers].map((viewer) => viewer.conversation))].sort();\n }\n\n function hand() {\n const path = deps.path();\n if (path === undefined) return;\n const open = viewed();\n const named = JSON.stringify(open);\n if (named === handed) return;\n handed = named;\n path.view(open);\n }\n\n function keptRecord(conversation: string): ConversationRecord {\n const carried = heldOf(conversation);\n return {\n conversation,\n messages: carried.messages,\n cursor: carried.cursor,\n summary: carried.summary,\n };\n }\n\n async function settle(local: RuntimeStore, conversation: string) {\n const sent = instructionOf(conversation).turn;\n if (sent === null) return;\n if (!heldOf(conversation).messages.some((entry) => entry.turn === sent)) return;\n composed.delete(conversation);\n await local.dropInstruction(conversation);\n }\n\n async function keep(\n conversation: string,\n next: (carried: Held) => Held | null,\n ): Promise<boolean> {\n const kept = await deps.durably(async (local) => {\n const following = next(heldOf(conversation));\n if (following === null) return false;\n held.set(conversation, following);\n await local.keepConversation(keptRecord(conversation));\n await settle(local, conversation);\n return true;\n });\n if (kept) emit(conversation);\n return kept;\n }\n\n async function keepInstruction(conversation: string, next: (unsent: Composed) => Composed) {\n await deps.durably(async (local) => {\n const stored = next(instructionOf(conversation));\n composed.set(conversation, stored);\n await local.keepInstruction({ conversation, ...stored });\n await settle(local, conversation);\n });\n emit(conversation);\n }\n\n async function dropInstruction(conversation: string) {\n await deps.durably(async (local) => {\n composed.delete(conversation);\n await local.dropInstruction(conversation);\n });\n emit(conversation);\n }\n\n function supersede(conversation: string) {\n issued.set(conversation, (issued.get(conversation) ?? 0) + 1);\n }\n\n async function fill(conversation: string, cursor: string | null): Promise<CallResult> {\n const generation = issued.get(conversation);\n const result = await deps.call('conversation.history', {\n conversation,\n ...(cursor === null ? {} : { cursor }),\n });\n const page = historyPage(result);\n if (page === null) return result;\n const landed = await keep(conversation, (carried) => {\n if (issued.get(conversation) !== generation) return null;\n if (cursor !== null) return carried.cursor === cursor ? older(carried, page) : null;\n return newest(carried, page, live.get(conversation) ?? NO_TURNS);\n });\n if (landed && cursor === null) live.delete(conversation);\n return result;\n }\n\n function invoke(\n name: ConversationAction,\n conversation: string,\n extra: Readonly<Record<string, unknown>> = {},\n ): Promise<CallResult> {\n return deps.call(name, { conversation, ...extra });\n }\n\n const surface: ConversationSurface = {\n list() {\n const declaration = deps.cards();\n if (declaration === undefined) return Promise.resolve([]);\n const documents = deps\n .documents()\n .documents.filter((document) => document.room === declaration.locator);\n const entries: ConversationEntry[] = [];\n for (const card of documents) {\n if (card.type !== declaration.type) continue;\n const identity = card.fields[declaration.identity];\n if (typeof identity !== 'string') continue;\n const agent = documents.find((document) =>\n document.backlinks.some(\n (backlink) => backlink.path === card.path && backlink.field === declaration.agent,\n ),\n );\n entries.push({ conversation: identity, card, agent: agent ?? null });\n }\n entries.sort((left, right) => (left.conversation < right.conversation ? -1 : 1));\n return Promise.resolve(entries);\n },\n read(conversation: string) {\n return deps.durably(() => Promise.resolve(viewOf(conversation)));\n },\n older(conversation: string) {\n const cursor = heldOf(conversation).cursor;\n if (cursor === null) return Promise.resolve(null);\n return fill(conversation, cursor);\n },\n compose(conversation: string, supplied: UnsentInstruction) {\n return keepInstruction(conversation, () => ({\n text: supplied.text,\n files: [...supplied.files],\n turn: null,\n }));\n },\n discard(conversation: string) {\n return dropInstruction(conversation);\n },\n create(input: unknown) {\n return deps.call('conversation.create', input);\n },\n async send(conversation: string) {\n const unsent = instructionOf(conversation);\n const files = await Promise.all(\n unsent.files.map(async (file) => ({ ...(await declaredFile(file)), blob: file.blob })),\n );\n const result = await invoke('conversation.send', conversation, { text: unsent.text, files });\n const turn = turnOf(result);\n if (turn === null) return result;\n await keepInstruction(conversation, (stored) => ({ ...stored, turn }));\n return result;\n },\n answer(conversation: string, answer: unknown) {\n return invoke('conversation.answer', conversation, { answer });\n },\n interrupt(conversation: string) {\n return invoke('conversation.interrupt', conversation);\n },\n kill(conversation: string) {\n return invoke('conversation.kill', conversation);\n },\n async cancel(conversation: string, turn: string) {\n const result = await invoke('conversation.cancel', conversation, { turn });\n if (result.kind !== 'action') return result;\n if (instructionOf(conversation).turn === turn) {\n await keepInstruction(conversation, (stored) => ({ ...stored, turn: null }));\n }\n return result;\n },\n async delete(conversation: string) {\n const result = await invoke('conversation.delete', conversation);\n if (result.kind !== 'action') return result;\n growing.delete(conversation);\n live.delete(conversation);\n supersede(conversation);\n await deps.durably(async (local) => {\n held.delete(conversation);\n composed.delete(conversation);\n await local.dropConversation(conversation);\n await local.dropInstruction(conversation);\n });\n emit(conversation);\n return result;\n },\n };\n\n return {\n surface,\n hydrate(conversations, instructions) {\n held.clear();\n for (const stored of conversations) {\n held.set(stored.conversation, {\n messages: stored.messages,\n cursor: stored.cursor,\n summary: stored.summary,\n });\n }\n composed.clear();\n for (const stored of instructions) {\n composed.set(stored.conversation, {\n text: stored.text,\n files: stored.files,\n turn: stored.turn,\n });\n }\n },\n observe(conversation: string, notify: (view: ConversationView) => void) {\n const first = !viewed().includes(conversation);\n const viewer: Viewing = { conversation, notify, ready: false };\n viewers.add(viewer);\n if (first) {\n live.set(conversation, new Set());\n supersede(conversation);\n }\n hand();\n void deps\n .durably(() => Promise.resolve())\n .then(async () => {\n if (deps.closed() || !viewers.has(viewer)) return;\n viewer.ready = true;\n viewer.notify(viewOf(conversation));\n if (first) await fill(conversation, null);\n })\n .catch(() => {});\n return () => {\n if (!viewers.delete(viewer)) return;\n if (!viewed().includes(conversation)) {\n growing.delete(conversation);\n live.delete(conversation);\n }\n hand();\n };\n },\n receive(event: ConversationEvent) {\n if (deps.closed() || !viewed().includes(event.conversation)) return;\n if (event.kind === 'growing-text') {\n growing.set(event.conversation, { turn: event.turn, text: event.text });\n emit(event.conversation);\n return;\n }\n if (event.kind === 'session-summary') {\n const summary = structuredClone(event.summary);\n void keep(event.conversation, (carried) => ({ ...carried, summary })).catch(() => {});\n return;\n }\n const arriving = carriedMessage(event.message);\n if (arriving === null) return;\n live.get(event.conversation)?.add(arriving.turn);\n if (growing.get(event.conversation)?.turn === arriving.turn) {\n growing.delete(event.conversation);\n }\n void deps\n .durably(async (local) => {\n held.set(event.conversation, sealed(heldOf(event.conversation), arriving));\n await local.keepConversation(keptRecord(event.conversation));\n await settle(local, event.conversation);\n })\n .then(() => {\n emit(event.conversation);\n })\n .catch(() => {});\n },\n close() {\n viewers.clear();\n growing.clear();\n live.clear();\n },\n };\n}\n"],"names":["declaredFile","NO_TURNS","Set","carriedMessage","value","record","turn","structuredClone","historyPage","result","kind","answer","Array","isArray","messages","entry","carried","push","cursor","turnOf","newest","held","page","arrived","arriving","map","overlap","findIndex","has","slice","placed","live","filter","older","present","sealed","at","createConversationStore","deps","Map","composed","growing","viewers","issued","handed","heldOf","conversation","get","summary","instructionOf","text","files","viewOf","unsent","olderPages","growingText","instruction","undefined","emit","closed","viewer","ready","notify","viewed","sort","hand","path","open","named","JSON","stringify","view","keptRecord","settle","local","sent","some","delete","dropInstruction","keep","next","kept","durably","following","set","keepConversation","keepInstruction","stored","supersede","fill","generation","call","landed","invoke","name","extra","surface","list","declaration","cards","Promise","resolve","documents","document","room","locator","entries","card","type","identity","fields","agent","find","backlinks","backlink","field","left","right","read","compose","supplied","discard","create","input","send","all","file","blob","interrupt","kill","cancel","dropConversation","hydrate","conversations","instructions","clear","observe","first","includes","add","then","catch","receive","event","message","close"],"mappings":"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"}
1
+ {"version":3,"sources":["/workspace/packages/mdruntime/src/conversation.ts"],"sourcesContent":["import type { QueryDocument } from '@agentshouse/query';\nimport type {\n AcceptedMessage,\n ConversationAction,\n ConversationCards,\n ConversationEvent,\n ConversationHistoryPage,\n ConversationMessage,\n ConversationStream,\n} from './adapter.js';\nimport { conversationChangeSet, type ChangeSet, type MessageChange } from './change-set.js';\nimport { declaredFile, type ChatDraftFile } from './file.js';\nimport type { CallResult } from './outcome.js';\nimport type { CycleProgress } from './status.js';\nimport type { ChatDraftRecord, HeldConversation, RuntimeStore } from './store.js';\n\nexport type ConversationEntry = {\n conversation: string;\n card: QueryDocument;\n agent: QueryDocument | null;\n};\n\nexport type GrowingText = { turn: string; text: string };\n\nexport type ChatDraft = {\n text: string;\n files: readonly ChatDraftFile[];\n};\n\nexport type ConversationOptions = { limit?: number };\n\nexport type ConversationView = {\n conversation: string;\n messages: readonly ConversationMessage[];\n growingText: GrowingText | null;\n summary: unknown;\n chatDraft: ChatDraft | null;\n};\n\nexport type ConversationSurface = {\n list(): Promise<readonly ConversationEntry[]>;\n read(conversation: string, options?: ConversationOptions): Promise<ConversationView>;\n create(input: unknown): Promise<CallResult>;\n send(conversation: string): Promise<CallResult>;\n answer(conversation: string, answer: unknown): Promise<CallResult>;\n interrupt(conversation: string): Promise<CallResult>;\n kill(conversation: string): Promise<CallResult>;\n cancel(conversation: string, turn: string): Promise<CallResult>;\n delete(conversation: string): Promise<CallResult>;\n};\n\nexport type ChatDraftSurface = {\n write(conversation: string, draft: ChatDraft): Promise<void>;\n discard(conversation: string): Promise<void>;\n};\n\nexport type ConversationDependencies = {\n cards(): ConversationCards | undefined;\n documents(): readonly QueryDocument[];\n call(name: ConversationAction, input: unknown): Promise<CallResult>;\n durably<T>(work: (local: RuntimeStore) => Promise<T>): Promise<T>;\n stream(): ConversationStream | undefined;\n publish(set: ChangeSet): void;\n closed(): boolean;\n};\n\nexport type ConversationStore = {\n surface: ConversationSurface;\n chatDraft: ChatDraftSurface;\n hydrate(held: readonly HeldConversation[], drafts: readonly ChatDraftRecord[]): void;\n reconcile(): Promise<void>;\n catchUp(progress: CycleProgress): Promise<void>;\n current(): boolean;\n reconnected(): void;\n observe(\n conversation: string,\n options: ConversationOptions,\n notify: (view: ConversationView) => void,\n ): () => void;\n changed(set: ChangeSet): void;\n receive(event: ConversationEvent): void;\n close(): void;\n};\n\ntype Watcher = {\n notify: (view: ConversationView) => void;\n ready: boolean;\n};\n\ntype Sending = { draft: ChatDraftRecord };\n\ntype SharedView = {\n conversation: string;\n limit: number | undefined;\n watchers: Set<Watcher>;\n};\n\nfunction ordered(left: AcceptedMessage, right: AcceptedMessage): number {\n if (left.position !== right.position) return left.position < right.position ? -1 : 1;\n if (left.identity !== right.identity) return left.identity < right.identity ? -1 : 1;\n return 0;\n}\n\nfunction merged(\n held: readonly AcceptedMessage[],\n arriving: readonly AcceptedMessage[],\n): readonly AcceptedMessage[] {\n const byIdentity = new Map(held.map((message) => [message.identity, message]));\n for (const message of arriving) byIdentity.set(message.identity, message);\n return [...byIdentity.values()].sort(ordered);\n}\n\nfunction acceptedMessage(value: unknown): AcceptedMessage | null {\n if (typeof value !== 'object' || value === null) return null;\n const record = value as Partial<Record<keyof AcceptedMessage, unknown>>;\n if (\n typeof record.identity !== 'string' ||\n typeof record.turn !== 'string' ||\n typeof record.position !== 'string' ||\n typeof record.text !== 'string'\n ) {\n return null;\n }\n return {\n identity: record.identity,\n turn: record.turn,\n position: record.position,\n text: record.text,\n message: structuredClone(record.message),\n };\n}\n\nfunction historyPage(result: CallResult): ConversationHistoryPage | null {\n if (result.kind !== 'action') return null;\n const answer = result.result;\n if (typeof answer !== 'object' || answer === null) return null;\n const record = answer as { messages?: unknown; next?: unknown };\n if (!Array.isArray(record.messages)) return null;\n if (record.next !== undefined && typeof record.next !== 'string') return null;\n const messages: AcceptedMessage[] = [];\n for (const entry of record.messages) {\n const message = acceptedMessage(entry);\n if (message === null) return null;\n messages.push(message);\n }\n return { messages, ...(record.next === undefined ? {} : { next: record.next }) };\n}\n\nfunction turnOf(result: CallResult): string | null {\n if (result.kind !== 'action') return null;\n const answer = result.result;\n if (typeof answer !== 'object' || answer === null) return null;\n const record = answer as { turn?: unknown };\n return typeof record.turn === 'string' ? record.turn : null;\n}\n\nfunction limitOf(options: ConversationOptions): number | undefined {\n const { limit } = options;\n if (limit === undefined) return undefined;\n if (!Number.isInteger(limit) || limit < 0) {\n throw new Error(`conversation limit must be a non-negative integer, got ${String(limit)}`);\n }\n return limit;\n}\n\nexport function createConversationStore(deps: ConversationDependencies): ConversationStore {\n const messages = new Map<string, readonly AcceptedMessage[]>();\n const reads = new Map<string, string | null>();\n const drafts = new Map<string, ChatDraftRecord>();\n const sending = new Map<string, Sending>();\n const behind = new Set<string>();\n const gaps = new Map<string, number>();\n const growing = new Map<string, GrowingText>();\n const summaries = new Map<string, unknown>();\n const views = new Map<string, SharedView>();\n let replicated: ReadonlySet<string> = new Set();\n let handedReplicated: string | undefined;\n let handedViewed: string | undefined;\n\n function viewOf(conversation: string, limit: number | undefined): ConversationView {\n const held = messages.get(conversation) ?? [];\n const shown = limit === undefined ? held : held.slice(Math.max(0, held.length - limit));\n const draft = drafts.get(conversation);\n return {\n conversation,\n messages: shown.map(({ identity, turn, text, message }) => ({\n identity,\n turn,\n text,\n message: structuredClone(message),\n })),\n growingText: growing.get(conversation) ?? null,\n summary: structuredClone(summaries.get(conversation) ?? null),\n chatDraft:\n draft === undefined || draft.turn !== null || sending.get(conversation)?.draft === draft\n ? null\n : { text: draft.text, files: [...draft.files] },\n };\n }\n\n function emit(conversation: string) {\n if (deps.closed()) return;\n for (const view of views.values()) {\n if (view.conversation !== conversation) continue;\n const ready = [...view.watchers].filter((watcher) => watcher.ready);\n if (ready.length === 0) continue;\n const value = viewOf(conversation, view.limit);\n for (const watcher of ready) watcher.notify(value);\n }\n }\n\n function viewed(): readonly string[] {\n return [...new Set([...views.values()].map((view) => view.conversation))].sort();\n }\n\n function handViewed() {\n const stream = deps.stream();\n if (stream === undefined) return;\n const open = viewed();\n const named = JSON.stringify(open);\n if (named === handedViewed) return;\n handedViewed = named;\n stream.view(open);\n }\n\n function handReplicated() {\n const stream = deps.stream();\n if (stream === undefined) return;\n const held = [...replicated].sort();\n const named = JSON.stringify(held);\n if (named === handedReplicated) return;\n handedReplicated = named;\n stream.replicate(held);\n }\n\n function carded(\n documents: readonly QueryDocument[],\n ): readonly { conversation: string; card: QueryDocument }[] {\n const declaration = deps.cards();\n if (declaration === undefined) return [];\n const cards: { conversation: string; card: QueryDocument }[] = [];\n for (const card of documents) {\n if (card.room !== declaration.locator || card.type !== declaration.type) continue;\n const identity = card.fields[declaration.identity];\n if (typeof identity === 'string') cards.push({ conversation: identity, card });\n }\n return cards;\n }\n\n async function remove(leaving: readonly string[]) {\n await deps.durably(async (local) => {\n await local.dropConversations(leaving);\n const removed: MessageChange[] = [];\n const changed: string[] = [];\n for (const conversation of leaving) {\n for (const message of messages.get(conversation) ?? []) {\n removed.push({ conversation, identity: message.identity });\n }\n if (\n messages.has(conversation) ||\n drafts.has(conversation) ||\n growing.has(conversation) ||\n summaries.has(conversation)\n ) {\n changed.push(conversation);\n }\n messages.delete(conversation);\n reads.delete(conversation);\n drafts.delete(conversation);\n behind.delete(conversation);\n growing.delete(conversation);\n summaries.delete(conversation);\n }\n if (changed.length > 0) deps.publish(conversationChangeSet(removed, changed));\n });\n }\n\n function gap(conversation: string) {\n gaps.set(conversation, (gaps.get(conversation) ?? 0) + 1);\n behind.add(conversation);\n }\n\n function keep(conversation: string, message: AcceptedMessage) {\n return deps.durably(async (local) => {\n if (!replicated.has(conversation)) return;\n const read = reads.get(conversation);\n const advances =\n read !== undefined &&\n !behind.has(conversation) &&\n (read === null || message.position > read);\n const sealed = drafts.get(conversation)?.turn === message.turn;\n await local.keepMessages({\n conversation,\n messages: [message],\n ...(advances ? { read: message.position } : {}),\n sealed,\n });\n messages.set(conversation, merged(messages.get(conversation) ?? [], [message]));\n if (advances) reads.set(conversation, message.position);\n if (sealed) drafts.delete(conversation);\n if (growing.get(conversation)?.turn === message.turn) growing.delete(conversation);\n deps.publish(\n conversationChangeSet([{ conversation, identity: message.identity }], [conversation]),\n );\n });\n }\n\n async function readHistory(conversation: string): Promise<CallResult | null> {\n const generation = gaps.get(conversation) ?? 0;\n const from = reads.get(conversation);\n const arriving: AcceptedMessage[] = [];\n let after = from ?? undefined;\n for (;;) {\n const result = await deps.call('conversation.history', {\n conversation,\n ...(after === undefined ? {} : { after }),\n });\n const page = historyPage(result);\n if (page === null) return result;\n arriving.push(...page.messages);\n if (page.next === undefined) break;\n after = page.next;\n }\n await deps.durably(async (local) => {\n if (!replicated.has(conversation)) return;\n const newest = arriving.reduce<string | null>(\n (top, message) => (top === null || message.position > top ? message.position : top),\n from ?? null,\n );\n const turn = drafts.get(conversation)?.turn;\n const sealed = arriving.some((message) => message.turn === turn);\n await local.keepMessages({ conversation, messages: arriving, read: newest, sealed });\n messages.set(conversation, merged(messages.get(conversation) ?? [], arriving));\n reads.set(conversation, newest);\n if (sealed) drafts.delete(conversation);\n const growingTurn = growing.get(conversation)?.turn;\n if (arriving.some((message) => message.turn === growingTurn)) growing.delete(conversation);\n if ((gaps.get(conversation) ?? 0) === generation) behind.delete(conversation);\n if (arriving.length > 0 || sealed) {\n deps.publish(\n conversationChangeSet(\n arriving.map((message) => ({ conversation, identity: message.identity })),\n [conversation],\n ),\n );\n }\n });\n return null;\n }\n\n function withDraft(\n conversation: string,\n next: (draft: ChatDraftRecord | undefined) => ChatDraftRecord | null | undefined,\n ): Promise<void> {\n return deps.durably(async (local) => {\n const following = next(drafts.get(conversation));\n if (following === undefined) return;\n if (following === null) {\n await local.dropChatDraft(conversation);\n drafts.delete(conversation);\n } else {\n await local.keepChatDraft(following);\n drafts.set(conversation, following);\n }\n deps.publish(conversationChangeSet([], [conversation]));\n });\n }\n\n function invoke(\n name: ConversationAction,\n conversation: string,\n extra: Readonly<Record<string, unknown>> = {},\n ): Promise<CallResult> {\n return deps.call(name, { conversation, ...extra });\n }\n\n const surface: ConversationSurface = {\n list() {\n const declaration = deps.cards();\n if (declaration === undefined) return Promise.resolve([]);\n const documents = deps\n .documents()\n .filter((document) => document.room === declaration.locator);\n const entries: ConversationEntry[] = carded(documents).map(({ conversation, card }) => ({\n conversation,\n card,\n agent:\n documents.find((document) =>\n document.backlinks.some(\n (backlink) => backlink.path === card.path && backlink.field === declaration.agent,\n ),\n ) ?? null,\n }));\n entries.sort((left, right) => (left.conversation < right.conversation ? -1 : 1));\n return Promise.resolve(entries);\n },\n async read(conversation: string, options: ConversationOptions = {}) {\n const limit = limitOf(options);\n return deps.durably(() => Promise.resolve(viewOf(conversation, limit)));\n },\n create(input: unknown) {\n return deps.call('conversation.create', input);\n },\n async send(conversation: string) {\n const draft = drafts.get(conversation);\n const pending: Sending | undefined = draft === undefined ? undefined : { draft };\n if (pending !== undefined) {\n sending.set(conversation, pending);\n deps.publish(conversationChangeSet([], [conversation]));\n }\n try {\n const files = await Promise.all(\n (draft?.files ?? []).map(async (file) => ({\n ...(await declaredFile(file)),\n blob: file.blob,\n })),\n );\n const result = await invoke('conversation.send', conversation, {\n text: draft?.text ?? '',\n files,\n });\n const turn = turnOf(result);\n if (turn === null || draft === undefined) return result;\n await withDraft(conversation, (current) => {\n if (current !== draft) return undefined;\n const sealed = (messages.get(conversation) ?? []).some(\n (message) => message.turn === turn,\n );\n return sealed ? null : { ...draft, turn };\n });\n return result;\n } finally {\n if (pending !== undefined && sending.get(conversation) === pending) {\n sending.delete(conversation);\n if (drafts.get(conversation) === draft) {\n deps.publish(conversationChangeSet([], [conversation]));\n }\n }\n }\n },\n answer(conversation: string, answer: unknown) {\n return invoke('conversation.answer', conversation, { answer });\n },\n interrupt(conversation: string) {\n return invoke('conversation.interrupt', conversation);\n },\n kill(conversation: string) {\n return invoke('conversation.kill', conversation);\n },\n async cancel(conversation: string, turn: string) {\n const result = await invoke('conversation.cancel', conversation, { turn });\n if (result.kind !== 'action') return result;\n await withDraft(conversation, (current) =>\n current === undefined || current.turn !== turn ? undefined : { ...current, turn: null },\n );\n return result;\n },\n delete(conversation: string) {\n return invoke('conversation.delete', conversation);\n },\n };\n\n const chatDraft: ChatDraftSurface = {\n write(conversation: string, draft: ChatDraft) {\n return withDraft(conversation, () => ({\n conversation,\n text: draft.text,\n files: [...draft.files],\n turn: null,\n }));\n },\n discard(conversation: string) {\n return withDraft(conversation, (current) => (current === undefined ? undefined : null));\n },\n };\n\n return {\n surface,\n chatDraft,\n hydrate(held, stored) {\n messages.clear();\n reads.clear();\n for (const entry of held) {\n messages.set(entry.conversation, [...entry.messages].sort(ordered));\n if (entry.read !== undefined) reads.set(entry.conversation, entry.read);\n }\n drafts.clear();\n for (const record of stored) drafts.set(record.conversation, record);\n },\n async reconcile() {\n const named = new Set(carded(deps.documents()).map((entry) => entry.conversation));\n const leaving = [\n ...new Set([...replicated, ...messages.keys(), ...reads.keys(), ...drafts.keys()]),\n ].filter((conversation) => !named.has(conversation));\n for (const conversation of named) {\n if (!replicated.has(conversation)) behind.add(conversation);\n }\n replicated = named;\n handReplicated();\n if (leaving.length > 0) await remove(leaving);\n },\n async catchUp(progress) {\n for (const conversation of [...behind].sort()) {\n if (deps.closed()) return;\n if (!replicated.has(conversation)) continue;\n const failed = await readHistory(conversation);\n if (failed?.kind === 'transport-uncertainty') progress.reachable = false;\n }\n if (behind.size > 0) progress.complete = false;\n },\n current() {\n return behind.size === 0;\n },\n reconnected() {\n for (const conversation of replicated) gap(conversation);\n },\n observe(conversation, options, notify) {\n const limit = limitOf(options);\n const key = JSON.stringify([conversation, limit ?? null]);\n const view = views.get(key) ?? { conversation, limit, watchers: new Set<Watcher>() };\n views.set(key, view);\n const watcher: Watcher = { notify, ready: false };\n view.watchers.add(watcher);\n handViewed();\n void deps\n .durably(() => Promise.resolve())\n .then(() => {\n if (deps.closed() || !view.watchers.has(watcher)) return;\n watcher.ready = true;\n watcher.notify(viewOf(conversation, limit));\n })\n .catch(() => {});\n return () => {\n if (!view.watchers.delete(watcher)) return;\n if (view.watchers.size === 0) views.delete(key);\n if (!viewed().includes(conversation)) {\n growing.delete(conversation);\n summaries.delete(conversation);\n }\n handViewed();\n };\n },\n changed(set) {\n for (const conversation of set.conversations) emit(conversation);\n },\n receive(event) {\n if (deps.closed()) return;\n const { conversation } = event;\n if (event.kind === 'gap') {\n if (replicated.has(conversation)) gap(conversation);\n return;\n }\n if (event.kind === 'growing-text') {\n if (!viewed().includes(conversation)) return;\n growing.set(conversation, { turn: event.turn, text: event.text });\n emit(conversation);\n return;\n }\n if (event.kind === 'session-summary') {\n if (!viewed().includes(conversation)) return;\n summaries.set(conversation, structuredClone(event.summary));\n emit(conversation);\n return;\n }\n const arriving = acceptedMessage(event.message);\n if (arriving === null || !replicated.has(conversation)) return;\n void keep(conversation, arriving).catch(() => {});\n },\n close() {\n views.clear();\n growing.clear();\n summaries.clear();\n },\n };\n}\n"],"names":["conversationChangeSet","declaredFile","ordered","left","right","position","identity","merged","held","arriving","byIdentity","Map","map","message","set","values","sort","acceptedMessage","value","record","turn","text","structuredClone","historyPage","result","kind","answer","Array","isArray","messages","next","undefined","entry","push","turnOf","limitOf","options","limit","Number","isInteger","Error","String","createConversationStore","deps","reads","drafts","sending","behind","Set","gaps","growing","summaries","views","replicated","handedReplicated","handedViewed","viewOf","conversation","get","shown","slice","Math","max","length","draft","growingText","summary","chatDraft","files","emit","closed","view","ready","watchers","filter","watcher","notify","viewed","handViewed","stream","open","named","JSON","stringify","handReplicated","replicate","carded","documents","declaration","cards","card","room","locator","type","fields","remove","leaving","durably","local","dropConversations","removed","changed","has","delete","publish","gap","add","keep","read","advances","sealed","keepMessages","readHistory","generation","from","after","call","page","newest","reduce","top","some","growingTurn","withDraft","following","dropChatDraft","keepChatDraft","invoke","name","extra","surface","list","Promise","resolve","document","entries","agent","find","backlinks","backlink","path","field","create","input","send","pending","all","file","blob","current","interrupt","kill","cancel","write","discard","hydrate","stored","clear","reconcile","keys","catchUp","progress","failed","reachable","size","complete","reconnected","observe","key","then","catch","includes","conversations","receive","event","close"],"mappings":"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"}
package/dist/file.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type InstructionFile = {
1
+ export type ChatDraftFile = {
2
2
  name: string;
3
3
  blob: Blob;
4
4
  };
@@ -16,5 +16,5 @@ export type Extent = {
16
16
  };
17
17
  export declare function extentOf(bytes: Uint8Array): Extent | null;
18
18
  export declare function hexDigest(digest: ArrayBuffer): string;
19
- export declare function declaredFile(file: InstructionFile): Promise<FileDeclaration>;
19
+ export declare function declaredFile(file: ChatDraftFile): Promise<FileDeclaration>;
20
20
  //# sourceMappingURL=file.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../src/file.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AA2GvD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAQzD;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAErD;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAUlF"}
1
+ {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../src/file.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AA2GvD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAQzD;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAErD;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CAUhF"}
package/dist/file.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdruntime/src/file.ts"],"sourcesContent":["export type InstructionFile = {\n name: string;\n blob: Blob;\n};\n\nexport type FileDeclaration = {\n name: string;\n mediaType: string;\n byteLength: number;\n contentHash: string;\n width?: number;\n height?: number;\n};\n\nexport type Extent = { width: number; height: number };\n\nconst PNG_SIGNATURE = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a];\nconst WEBP_SYNC = [0x9d, 0x01, 0x2a];\nconst SHAPELESS_JPEG_MARKERS = new Set([0xc4, 0xc8, 0xcc]);\nconst BMFF_CONTAINERS = new Set(['meta', 'iprp', 'ipco']);\n\nfunction starts(bytes: Uint8Array, signature: readonly number[], at = 0): boolean {\n return signature.every((value, index) => bytes[at + index] === value);\n}\n\nfunction text(bytes: Uint8Array, at: number, length: number): string {\n return String.fromCharCode(...bytes.subarray(at, at + length));\n}\n\nfunction bigEndian(bytes: Uint8Array, at: number, length: number): number {\n let value = 0;\n for (let index = 0; index < length; index += 1) value = value * 256 + (bytes[at + index] ?? 0);\n return value;\n}\n\nfunction littleEndian(bytes: Uint8Array, at: number, length: number): number {\n let value = 0;\n for (let index = length - 1; index >= 0; index -= 1)\n value = value * 256 + (bytes[at + index] ?? 0);\n return value;\n}\n\nfunction pngExtent(bytes: Uint8Array): Extent | null {\n if (bytes.length < 24 || !starts(bytes, PNG_SIGNATURE)) return null;\n if (text(bytes, 12, 4) !== 'IHDR') return null;\n return { width: bigEndian(bytes, 16, 4), height: bigEndian(bytes, 20, 4) };\n}\n\nfunction gifExtent(bytes: Uint8Array): Extent | null {\n if (bytes.length < 10 || text(bytes, 0, 3) !== 'GIF') return null;\n return { width: littleEndian(bytes, 6, 2), height: littleEndian(bytes, 8, 2) };\n}\n\nfunction jpegExtent(bytes: Uint8Array): Extent | null {\n if (bytes.length < 4 || bytes[0] !== 0xff || bytes[1] !== 0xd8) return null;\n let at = 2;\n while (at + 9 < bytes.length) {\n if (bytes[at] !== 0xff) return null;\n const marker = bytes[at + 1] ?? 0;\n if (marker === 0xd8 || marker === 0x01 || (marker >= 0xd0 && marker <= 0xd7)) {\n at += 2;\n continue;\n }\n const length = bigEndian(bytes, at + 2, 2);\n if (marker >= 0xc0 && marker <= 0xcf && !SHAPELESS_JPEG_MARKERS.has(marker)) {\n return { width: bigEndian(bytes, at + 7, 2), height: bigEndian(bytes, at + 5, 2) };\n }\n if (length < 2) return null;\n at += 2 + length;\n }\n return null;\n}\n\nfunction webpExtent(bytes: Uint8Array): Extent | null {\n if (bytes.length < 30 || text(bytes, 0, 4) !== 'RIFF' || text(bytes, 8, 4) !== 'WEBP')\n return null;\n const chunk = text(bytes, 12, 4);\n if (chunk === 'VP8X') {\n return {\n width: littleEndian(bytes, 24, 3) + 1,\n height: littleEndian(bytes, 27, 3) + 1,\n };\n }\n if (chunk === 'VP8 ' && starts(bytes, WEBP_SYNC, 23)) {\n return {\n width: littleEndian(bytes, 26, 2) & 0x3fff,\n height: littleEndian(bytes, 28, 2) & 0x3fff,\n };\n }\n if (chunk === 'VP8L' && bytes[20] === 0x2f) {\n const packed = littleEndian(bytes, 21, 4);\n return { width: (packed & 0x3fff) + 1, height: ((packed >>> 14) & 0x3fff) + 1 };\n }\n return null;\n}\n\nfunction spatialExtent(bytes: Uint8Array, from: number, to: number): Extent | null {\n let at = from;\n while (at + 8 <= to) {\n const size = bigEndian(bytes, at, 4);\n const name = text(bytes, at + 4, 4);\n const end = size === 0 ? to : at + size;\n if (size === 1 || end <= at || end > to) return null;\n if (name === 'ispe') {\n if (end < at + 20) return null;\n return { width: bigEndian(bytes, at + 12, 4), height: bigEndian(bytes, at + 16, 4) };\n }\n if (BMFF_CONTAINERS.has(name)) {\n const inner = spatialExtent(bytes, at + (name === 'meta' ? 12 : 8), end);\n if (inner !== null) return inner;\n }\n at = end;\n }\n return null;\n}\n\nfunction bmffExtent(bytes: Uint8Array): Extent | null {\n if (bytes.length < 16 || text(bytes, 4, 4) !== 'ftyp') return null;\n return spatialExtent(bytes, 0, bytes.length);\n}\n\nexport function extentOf(bytes: Uint8Array): Extent | null {\n return (\n pngExtent(bytes) ??\n jpegExtent(bytes) ??\n gifExtent(bytes) ??\n webpExtent(bytes) ??\n bmffExtent(bytes)\n );\n}\n\nexport function hexDigest(digest: ArrayBuffer): string {\n return [...new Uint8Array(digest)].map((value) => value.toString(16).padStart(2, '0')).join('');\n}\n\nexport async function declaredFile(file: InstructionFile): Promise<FileDeclaration> {\n const bytes = new Uint8Array(await file.blob.arrayBuffer());\n const extent = file.blob.type.startsWith('image/') ? extentOf(bytes) : null;\n return {\n name: file.name,\n mediaType: file.blob.type,\n byteLength: bytes.byteLength,\n contentHash: hexDigest(await crypto.subtle.digest('SHA-256', bytes)),\n ...(extent === null ? {} : extent),\n };\n}\n"],"names":["PNG_SIGNATURE","WEBP_SYNC","SHAPELESS_JPEG_MARKERS","Set","BMFF_CONTAINERS","starts","bytes","signature","at","every","value","index","text","length","String","fromCharCode","subarray","bigEndian","littleEndian","pngExtent","width","height","gifExtent","jpegExtent","marker","has","webpExtent","chunk","packed","spatialExtent","from","to","size","name","end","inner","bmffExtent","extentOf","hexDigest","digest","Uint8Array","map","toString","padStart","join","declaredFile","file","blob","arrayBuffer","extent","type","startsWith","mediaType","byteLength","contentHash","crypto","subtle"],"mappings":"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"}
1
+ {"version":3,"sources":["/workspace/packages/mdruntime/src/file.ts"],"sourcesContent":["export type ChatDraftFile = {\n name: string;\n blob: Blob;\n};\n\nexport type FileDeclaration = {\n name: string;\n mediaType: string;\n byteLength: number;\n contentHash: string;\n width?: number;\n height?: number;\n};\n\nexport type Extent = { width: number; height: number };\n\nconst PNG_SIGNATURE = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a];\nconst WEBP_SYNC = [0x9d, 0x01, 0x2a];\nconst SHAPELESS_JPEG_MARKERS = new Set([0xc4, 0xc8, 0xcc]);\nconst BMFF_CONTAINERS = new Set(['meta', 'iprp', 'ipco']);\n\nfunction starts(bytes: Uint8Array, signature: readonly number[], at = 0): boolean {\n return signature.every((value, index) => bytes[at + index] === value);\n}\n\nfunction text(bytes: Uint8Array, at: number, length: number): string {\n return String.fromCharCode(...bytes.subarray(at, at + length));\n}\n\nfunction bigEndian(bytes: Uint8Array, at: number, length: number): number {\n let value = 0;\n for (let index = 0; index < length; index += 1) value = value * 256 + (bytes[at + index] ?? 0);\n return value;\n}\n\nfunction littleEndian(bytes: Uint8Array, at: number, length: number): number {\n let value = 0;\n for (let index = length - 1; index >= 0; index -= 1)\n value = value * 256 + (bytes[at + index] ?? 0);\n return value;\n}\n\nfunction pngExtent(bytes: Uint8Array): Extent | null {\n if (bytes.length < 24 || !starts(bytes, PNG_SIGNATURE)) return null;\n if (text(bytes, 12, 4) !== 'IHDR') return null;\n return { width: bigEndian(bytes, 16, 4), height: bigEndian(bytes, 20, 4) };\n}\n\nfunction gifExtent(bytes: Uint8Array): Extent | null {\n if (bytes.length < 10 || text(bytes, 0, 3) !== 'GIF') return null;\n return { width: littleEndian(bytes, 6, 2), height: littleEndian(bytes, 8, 2) };\n}\n\nfunction jpegExtent(bytes: Uint8Array): Extent | null {\n if (bytes.length < 4 || bytes[0] !== 0xff || bytes[1] !== 0xd8) return null;\n let at = 2;\n while (at + 9 < bytes.length) {\n if (bytes[at] !== 0xff) return null;\n const marker = bytes[at + 1] ?? 0;\n if (marker === 0xd8 || marker === 0x01 || (marker >= 0xd0 && marker <= 0xd7)) {\n at += 2;\n continue;\n }\n const length = bigEndian(bytes, at + 2, 2);\n if (marker >= 0xc0 && marker <= 0xcf && !SHAPELESS_JPEG_MARKERS.has(marker)) {\n return { width: bigEndian(bytes, at + 7, 2), height: bigEndian(bytes, at + 5, 2) };\n }\n if (length < 2) return null;\n at += 2 + length;\n }\n return null;\n}\n\nfunction webpExtent(bytes: Uint8Array): Extent | null {\n if (bytes.length < 30 || text(bytes, 0, 4) !== 'RIFF' || text(bytes, 8, 4) !== 'WEBP')\n return null;\n const chunk = text(bytes, 12, 4);\n if (chunk === 'VP8X') {\n return {\n width: littleEndian(bytes, 24, 3) + 1,\n height: littleEndian(bytes, 27, 3) + 1,\n };\n }\n if (chunk === 'VP8 ' && starts(bytes, WEBP_SYNC, 23)) {\n return {\n width: littleEndian(bytes, 26, 2) & 0x3fff,\n height: littleEndian(bytes, 28, 2) & 0x3fff,\n };\n }\n if (chunk === 'VP8L' && bytes[20] === 0x2f) {\n const packed = littleEndian(bytes, 21, 4);\n return { width: (packed & 0x3fff) + 1, height: ((packed >>> 14) & 0x3fff) + 1 };\n }\n return null;\n}\n\nfunction spatialExtent(bytes: Uint8Array, from: number, to: number): Extent | null {\n let at = from;\n while (at + 8 <= to) {\n const size = bigEndian(bytes, at, 4);\n const name = text(bytes, at + 4, 4);\n const end = size === 0 ? to : at + size;\n if (size === 1 || end <= at || end > to) return null;\n if (name === 'ispe') {\n if (end < at + 20) return null;\n return { width: bigEndian(bytes, at + 12, 4), height: bigEndian(bytes, at + 16, 4) };\n }\n if (BMFF_CONTAINERS.has(name)) {\n const inner = spatialExtent(bytes, at + (name === 'meta' ? 12 : 8), end);\n if (inner !== null) return inner;\n }\n at = end;\n }\n return null;\n}\n\nfunction bmffExtent(bytes: Uint8Array): Extent | null {\n if (bytes.length < 16 || text(bytes, 4, 4) !== 'ftyp') return null;\n return spatialExtent(bytes, 0, bytes.length);\n}\n\nexport function extentOf(bytes: Uint8Array): Extent | null {\n return (\n pngExtent(bytes) ??\n jpegExtent(bytes) ??\n gifExtent(bytes) ??\n webpExtent(bytes) ??\n bmffExtent(bytes)\n );\n}\n\nexport function hexDigest(digest: ArrayBuffer): string {\n return [...new Uint8Array(digest)].map((value) => value.toString(16).padStart(2, '0')).join('');\n}\n\nexport async function declaredFile(file: ChatDraftFile): Promise<FileDeclaration> {\n const bytes = new Uint8Array(await file.blob.arrayBuffer());\n const extent = file.blob.type.startsWith('image/') ? extentOf(bytes) : null;\n return {\n name: file.name,\n mediaType: file.blob.type,\n byteLength: bytes.byteLength,\n contentHash: hexDigest(await crypto.subtle.digest('SHA-256', bytes)),\n ...(extent === null ? {} : extent),\n };\n}\n"],"names":["PNG_SIGNATURE","WEBP_SYNC","SHAPELESS_JPEG_MARKERS","Set","BMFF_CONTAINERS","starts","bytes","signature","at","every","value","index","text","length","String","fromCharCode","subarray","bigEndian","littleEndian","pngExtent","width","height","gifExtent","jpegExtent","marker","has","webpExtent","chunk","packed","spatialExtent","from","to","size","name","end","inner","bmffExtent","extentOf","hexDigest","digest","Uint8Array","map","toString","padStart","join","declaredFile","file","blob","arrayBuffer","extent","type","startsWith","mediaType","byteLength","contentHash","crypto","subtle"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAML,KAAK,WAAW,EAKjB,MAAM,WAAW,CAAC;AAEnB,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEpF,MAAM,MAAM,aAAa,GAAG;IAC1B,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7C,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,IAAI,CAAC;IACrE,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC,CAAC;AAkHF,wBAAgB,cAAc,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAiH3E;AAED,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAML,KAAK,WAAW,EAKjB,MAAM,WAAW,CAAC;AAEnB,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEpF,MAAM,MAAM,aAAa,GAAG;IAC1B,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7C,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,IAAI,CAAC;IACrE,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC,CAAC;AAqHF,wBAAgB,cAAc,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAkH3E;AAED,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
package/dist/host.js CHANGED
@@ -48,13 +48,7 @@ function answered(md, app, writtenBy, member, input, deploymentFacts) {
48
48
  case 'conversation.list':
49
49
  return md.conversation.list();
50
50
  case 'conversation.read':
51
- return md.conversation.read(input[0]);
52
- case 'conversation.older':
53
- return md.conversation.older(input[0]);
54
- case 'conversation.compose':
55
- return md.conversation.compose(input[0], input[1]);
56
- case 'conversation.discard':
57
- return md.conversation.discard(input[0]);
51
+ return md.conversation.read(input[0], input[1]);
58
52
  case 'conversation.create':
59
53
  return md.conversation.create(input[0]);
60
54
  case 'conversation.send':
@@ -69,6 +63,10 @@ function answered(md, app, writtenBy, member, input, deploymentFacts) {
69
63
  return md.conversation.cancel(input[0], input[1]);
70
64
  case 'conversation.delete':
71
65
  return md.conversation.delete(input[0]);
66
+ case 'chatDraft.write':
67
+ return md.chatDraft.write(input[0], input[1]);
68
+ case 'chatDraft.discard':
69
+ return md.chatDraft.discard(input[0]);
72
70
  }
73
71
  }
74
72
  function subscribed(md, app, topic, input, deliver) {
@@ -90,7 +88,7 @@ function subscribed(md, app, topic, input, deliver) {
90
88
  case 'presentation':
91
89
  return md.observe('presentation', app, deliver);
92
90
  case 'conversation':
93
- return md.observe('conversation', input[0], deliver);
91
+ return md.observe('conversation', input[0], input[1], deliver);
94
92
  }
95
93
  }
96
94
  export function serveMdRuntime(options) {
@@ -143,6 +141,7 @@ export function serveMdRuntime(options) {
143
141
  return;
144
142
  }
145
143
  try {
144
+ if (message.kind !== 'observe' || message.topic !== 'drafts') await md.loaded();
146
145
  if (message.kind === 'observe') {
147
146
  subscriptions.set(message.id, message.topic === 'deployment-facts' ? observeFacts((value)=>{
148
147
  if (serving) send({
package/dist/host.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdruntime/src/host.ts"],"sourcesContent":["import type { QueryOptions } from '@agentshouse/query';\nimport type { Change, WrittenBy } from './change.js';\nimport {\n createMdRuntime,\n type HistoryQuery,\n type MdRuntime,\n type MdRuntimeOptions,\n} from './connection.js';\nimport type { UnsentInstruction } from './conversation.js';\nimport { removeRuntimeStore } from './store.js';\nimport {\n AUTHORIZATION_ENDED,\n carried,\n envelope,\n PROTOCOL_MISMATCH,\n request,\n type RuntimePort,\n type WireAnswer,\n type WireMember,\n type WireRequest,\n type WireTopic,\n} from './wire.js';\n\nexport type MdRuntimeHostOptions = MdRuntimeOptions & { deploymentFacts?: unknown };\n\nexport type MdRuntimeHost = {\n replaceDeploymentFacts(value: unknown): void;\n attach(port: RuntimePort, app: string, release?: string): () => void;\n endAuthorization(): Promise<void>;\n};\n\nfunction answered(\n md: MdRuntime,\n app: string,\n writtenBy: WrittenBy | undefined,\n member: WireMember,\n input: readonly unknown[],\n deploymentFacts: unknown,\n): unknown {\n switch (member) {\n case 'rooms':\n return md.rooms();\n case 'slots':\n return md.slots();\n case 'query':\n return md.query(input[0] as QueryOptions | undefined);\n case 'types':\n return md.types(input[0] as string);\n case 'syncStatus':\n return md.syncStatus();\n case 'save':\n return md.save(\n input[0] as string,\n input[1] as readonly Change[],\n input[2] as string | undefined,\n writtenBy,\n );\n case 'outcome':\n return md.outcome(input[0] as string);\n case 'history':\n return md.history(input[0] as string, input[1] as string, input[2] as HistoryQuery);\n case 'call':\n return md.call(input[0] as string, input[1]);\n case 'log':\n return md.log();\n case 'storageLoss':\n return md.storageLoss();\n case 'deploymentFacts':\n return structuredClone(deploymentFacts);\n case 'persistence':\n return md.persistence();\n case 'reauthorize':\n return md.reauthorize();\n case 'draft.list':\n return md.draft.list();\n case 'draft.read':\n return md.draft.read(input[0] as string, input[1] as string);\n case 'draft.replace':\n return md.draft.replace(input[0] as string, input[1] as string, input[2]);\n case 'draft.discard':\n return md.draft.discard(input[0] as string, input[1] as string);\n case 'queue.discard':\n return md.queue.discard(input[0] as string, input[1] as string);\n case 'presentation.read':\n return md.presentation.read(app);\n case 'presentation.write':\n return md.presentation.write(app, input[0]);\n case 'conversation.list':\n return md.conversation.list();\n case 'conversation.read':\n return md.conversation.read(input[0] as string);\n case 'conversation.older':\n return md.conversation.older(input[0] as string);\n case 'conversation.compose':\n return md.conversation.compose(input[0] as string, input[1] as UnsentInstruction);\n case 'conversation.discard':\n return md.conversation.discard(input[0] as string);\n case 'conversation.create':\n return md.conversation.create(input[0]);\n case 'conversation.send':\n return md.conversation.send(input[0] as string);\n case 'conversation.answer':\n return md.conversation.answer(input[0] as string, input[1]);\n case 'conversation.interrupt':\n return md.conversation.interrupt(input[0] as string);\n case 'conversation.kill':\n return md.conversation.kill(input[0] as string);\n case 'conversation.cancel':\n return md.conversation.cancel(input[0] as string, input[1] as string);\n case 'conversation.delete':\n return md.conversation.delete(input[0] as string);\n }\n}\n\nfunction subscribed(\n md: MdRuntime,\n app: string,\n topic: Exclude<WireTopic, 'deployment-facts'>,\n input: readonly unknown[],\n deliver: (value: unknown) => void,\n): () => void {\n switch (topic) {\n case 'rooms':\n return md.observe('rooms', deliver);\n case 'connection-refusal':\n return md.observe('connection-refusal', deliver);\n case 'storage-loss':\n return md.observe('storage-loss', deliver);\n case 'sync-status':\n return md.observe('sync-status', deliver);\n case 'drafts':\n return md.observe('drafts', deliver);\n case 'queue':\n return md.observe('queue', input[0] as string, deliver);\n case 'query':\n return md.observe('query', input[0] as QueryOptions, deliver);\n case 'presentation':\n return md.observe('presentation', app, deliver);\n case 'conversation':\n return md.observe('conversation', input[0] as string, deliver);\n }\n}\n\nexport function serveMdRuntime(options: MdRuntimeHostOptions): MdRuntimeHost {\n let deploymentFacts = structuredClone(options.deploymentFacts);\n const stopping = new AbortController();\n const stop = () => {\n stopping.abort();\n };\n options.signal?.addEventListener('abort', stop, { once: true });\n if (options.signal?.aborted === true) stop();\n const md = createMdRuntime({ ...options, signal: stopping.signal });\n const attachments = new Map<() => void, (message: WireAnswer) => void>();\n let authorized = true;\n const factsObservers = new Set<(value: unknown) => void>();\n const observeFacts = (deliver: (value: unknown) => void) => {\n factsObservers.add(deliver);\n deliver(structuredClone(deploymentFacts));\n return () => {\n factsObservers.delete(deliver);\n };\n };\n\n function attach(port: RuntimePort, app: string, release?: string): () => void {\n if (!authorized) throw new Error(AUTHORIZATION_ENDED);\n const writtenBy = release === undefined ? undefined : { app, release };\n const subscriptions = new Map<number, () => void>();\n let serving = true;\n const send = (message: WireAnswer) => {\n port.postMessage(envelope(message));\n };\n const detach = () => {\n if (!serving) return;\n serving = false;\n for (const end of subscriptions.values()) end();\n subscriptions.clear();\n attachments.delete(detach);\n };\n const serve = async (message: WireRequest) => {\n if (message.kind === 'hello') return;\n if (message.kind === 'stop') {\n subscriptions.get(message.id)?.();\n subscriptions.delete(message.id);\n return;\n }\n try {\n if (message.kind === 'observe') {\n subscriptions.set(\n message.id,\n message.topic === 'deployment-facts'\n ? observeFacts((value) => {\n if (serving) send({ kind: 'event', id: message.id, value });\n })\n : subscribed(md, app, message.topic, message.input, (value) => {\n if (serving) send({ kind: 'event', id: message.id, value });\n }),\n );\n if (serving) send({ kind: 'result', id: message.id, value: null });\n return;\n }\n const value = await answered(\n md,\n app,\n writtenBy,\n message.member,\n message.input,\n deploymentFacts,\n );\n if (serving) send({ kind: 'result', id: message.id, value });\n } catch (error) {\n if (serving) {\n send({\n kind: 'failure',\n id: message.id,\n message: error instanceof Error ? error.message : String(error),\n });\n }\n }\n };\n port.addEventListener('message', (event) => {\n if (!serving) return;\n const wire = carried(event.data);\n if (wire === null) return;\n if (!wire.matching) {\n send({ kind: 'refusal', refusal: PROTOCOL_MISMATCH });\n detach();\n return;\n }\n const message = request(wire.message);\n if (message === null) return;\n void serve(message);\n });\n port.addEventListener('close', detach);\n port.start();\n attachments.set(detach, send);\n return detach;\n }\n\n return {\n attach,\n replaceDeploymentFacts(value) {\n if (!authorized) throw new Error(AUTHORIZATION_ENDED);\n deploymentFacts = structuredClone(value);\n for (const deliver of factsObservers) deliver(structuredClone(deploymentFacts));\n },\n async endAuthorization() {\n authorized = false;\n for (const [detach, send] of [...attachments]) {\n send({ kind: 'ended' });\n detach();\n }\n stop();\n await removeRuntimeStore();\n await options.shell.dropGeneration();\n },\n };\n}\n\nexport type { RuntimePort } from './wire.js';\n"],"names":["createMdRuntime","removeRuntimeStore","AUTHORIZATION_ENDED","carried","envelope","PROTOCOL_MISMATCH","request","answered","md","app","writtenBy","member","input","deploymentFacts","rooms","slots","query","types","syncStatus","save","outcome","history","call","log","storageLoss","structuredClone","persistence","reauthorize","draft","list","read","replace","discard","queue","presentation","write","conversation","older","compose","create","send","answer","interrupt","kill","cancel","delete","subscribed","topic","deliver","observe","serveMdRuntime","options","stopping","AbortController","stop","abort","signal","addEventListener","once","aborted","attachments","Map","authorized","factsObservers","Set","observeFacts","add","attach","port","release","Error","undefined","subscriptions","serving","message","postMessage","detach","end","values","clear","serve","kind","get","id","set","value","error","String","event","wire","data","matching","refusal","start","replaceDeploymentFacts","endAuthorization","shell","dropGeneration"],"mappings":"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"}
1
+ {"version":3,"sources":["/workspace/packages/mdruntime/src/host.ts"],"sourcesContent":["import type { QueryOptions } from '@agentshouse/query';\nimport type { Change, WrittenBy } from './change.js';\nimport {\n createMdRuntime,\n type HistoryQuery,\n type MdRuntime,\n type MdRuntimeOptions,\n} from './connection.js';\nimport type { ChatDraft, ConversationOptions } from './conversation.js';\nimport { removeRuntimeStore } from './store.js';\nimport {\n AUTHORIZATION_ENDED,\n carried,\n envelope,\n PROTOCOL_MISMATCH,\n request,\n type RuntimePort,\n type WireAnswer,\n type WireMember,\n type WireRequest,\n type WireTopic,\n} from './wire.js';\n\nexport type MdRuntimeHostOptions = MdRuntimeOptions & { deploymentFacts?: unknown };\n\nexport type MdRuntimeHost = {\n replaceDeploymentFacts(value: unknown): void;\n attach(port: RuntimePort, app: string, release?: string): () => void;\n endAuthorization(): Promise<void>;\n};\n\nfunction answered(\n md: MdRuntime,\n app: string,\n writtenBy: WrittenBy | undefined,\n member: WireMember,\n input: readonly unknown[],\n deploymentFacts: unknown,\n): unknown {\n switch (member) {\n case 'rooms':\n return md.rooms();\n case 'slots':\n return md.slots();\n case 'query':\n return md.query(input[0] as QueryOptions | undefined);\n case 'types':\n return md.types(input[0] as string);\n case 'syncStatus':\n return md.syncStatus();\n case 'save':\n return md.save(\n input[0] as string,\n input[1] as readonly Change[],\n input[2] as string | undefined,\n writtenBy,\n );\n case 'outcome':\n return md.outcome(input[0] as string);\n case 'history':\n return md.history(input[0] as string, input[1] as string, input[2] as HistoryQuery);\n case 'call':\n return md.call(input[0] as string, input[1]);\n case 'log':\n return md.log();\n case 'storageLoss':\n return md.storageLoss();\n case 'deploymentFacts':\n return structuredClone(deploymentFacts);\n case 'persistence':\n return md.persistence();\n case 'reauthorize':\n return md.reauthorize();\n case 'draft.list':\n return md.draft.list();\n case 'draft.read':\n return md.draft.read(input[0] as string, input[1] as string);\n case 'draft.replace':\n return md.draft.replace(input[0] as string, input[1] as string, input[2]);\n case 'draft.discard':\n return md.draft.discard(input[0] as string, input[1] as string);\n case 'queue.discard':\n return md.queue.discard(input[0] as string, input[1] as string);\n case 'presentation.read':\n return md.presentation.read(app);\n case 'presentation.write':\n return md.presentation.write(app, input[0]);\n case 'conversation.list':\n return md.conversation.list();\n case 'conversation.read':\n return md.conversation.read(input[0] as string, input[1] as ConversationOptions | undefined);\n case 'conversation.create':\n return md.conversation.create(input[0]);\n case 'conversation.send':\n return md.conversation.send(input[0] as string);\n case 'conversation.answer':\n return md.conversation.answer(input[0] as string, input[1]);\n case 'conversation.interrupt':\n return md.conversation.interrupt(input[0] as string);\n case 'conversation.kill':\n return md.conversation.kill(input[0] as string);\n case 'conversation.cancel':\n return md.conversation.cancel(input[0] as string, input[1] as string);\n case 'conversation.delete':\n return md.conversation.delete(input[0] as string);\n case 'chatDraft.write':\n return md.chatDraft.write(input[0] as string, input[1] as ChatDraft);\n case 'chatDraft.discard':\n return md.chatDraft.discard(input[0] as string);\n }\n}\n\nfunction subscribed(\n md: MdRuntime,\n app: string,\n topic: Exclude<WireTopic, 'deployment-facts'>,\n input: readonly unknown[],\n deliver: (value: unknown) => void,\n): () => void {\n switch (topic) {\n case 'rooms':\n return md.observe('rooms', deliver);\n case 'connection-refusal':\n return md.observe('connection-refusal', deliver);\n case 'storage-loss':\n return md.observe('storage-loss', deliver);\n case 'sync-status':\n return md.observe('sync-status', deliver);\n case 'drafts':\n return md.observe('drafts', deliver);\n case 'queue':\n return md.observe('queue', input[0] as string, deliver);\n case 'query':\n return md.observe('query', input[0] as QueryOptions, deliver);\n case 'presentation':\n return md.observe('presentation', app, deliver);\n case 'conversation':\n return md.observe(\n 'conversation',\n input[0] as string,\n input[1] as ConversationOptions,\n deliver,\n );\n }\n}\n\nexport function serveMdRuntime(options: MdRuntimeHostOptions): MdRuntimeHost {\n let deploymentFacts = structuredClone(options.deploymentFacts);\n const stopping = new AbortController();\n const stop = () => {\n stopping.abort();\n };\n options.signal?.addEventListener('abort', stop, { once: true });\n if (options.signal?.aborted === true) stop();\n const md = createMdRuntime({ ...options, signal: stopping.signal });\n const attachments = new Map<() => void, (message: WireAnswer) => void>();\n let authorized = true;\n const factsObservers = new Set<(value: unknown) => void>();\n const observeFacts = (deliver: (value: unknown) => void) => {\n factsObservers.add(deliver);\n deliver(structuredClone(deploymentFacts));\n return () => {\n factsObservers.delete(deliver);\n };\n };\n\n function attach(port: RuntimePort, app: string, release?: string): () => void {\n if (!authorized) throw new Error(AUTHORIZATION_ENDED);\n const writtenBy = release === undefined ? undefined : { app, release };\n const subscriptions = new Map<number, () => void>();\n let serving = true;\n const send = (message: WireAnswer) => {\n port.postMessage(envelope(message));\n };\n const detach = () => {\n if (!serving) return;\n serving = false;\n for (const end of subscriptions.values()) end();\n subscriptions.clear();\n attachments.delete(detach);\n };\n const serve = async (message: WireRequest) => {\n if (message.kind === 'hello') return;\n if (message.kind === 'stop') {\n subscriptions.get(message.id)?.();\n subscriptions.delete(message.id);\n return;\n }\n try {\n if (message.kind !== 'observe' || message.topic !== 'drafts') await md.loaded();\n if (message.kind === 'observe') {\n subscriptions.set(\n message.id,\n message.topic === 'deployment-facts'\n ? observeFacts((value) => {\n if (serving) send({ kind: 'event', id: message.id, value });\n })\n : subscribed(md, app, message.topic, message.input, (value) => {\n if (serving) send({ kind: 'event', id: message.id, value });\n }),\n );\n if (serving) send({ kind: 'result', id: message.id, value: null });\n return;\n }\n const value = await answered(\n md,\n app,\n writtenBy,\n message.member,\n message.input,\n deploymentFacts,\n );\n if (serving) send({ kind: 'result', id: message.id, value });\n } catch (error) {\n if (serving) {\n send({\n kind: 'failure',\n id: message.id,\n message: error instanceof Error ? error.message : String(error),\n });\n }\n }\n };\n port.addEventListener('message', (event) => {\n if (!serving) return;\n const wire = carried(event.data);\n if (wire === null) return;\n if (!wire.matching) {\n send({ kind: 'refusal', refusal: PROTOCOL_MISMATCH });\n detach();\n return;\n }\n const message = request(wire.message);\n if (message === null) return;\n void serve(message);\n });\n port.addEventListener('close', detach);\n port.start();\n attachments.set(detach, send);\n return detach;\n }\n\n return {\n attach,\n replaceDeploymentFacts(value) {\n if (!authorized) throw new Error(AUTHORIZATION_ENDED);\n deploymentFacts = structuredClone(value);\n for (const deliver of factsObservers) deliver(structuredClone(deploymentFacts));\n },\n async endAuthorization() {\n authorized = false;\n for (const [detach, send] of [...attachments]) {\n send({ kind: 'ended' });\n detach();\n }\n stop();\n await removeRuntimeStore();\n await options.shell.dropGeneration();\n },\n };\n}\n\nexport type { RuntimePort } from './wire.js';\n"],"names":["createMdRuntime","removeRuntimeStore","AUTHORIZATION_ENDED","carried","envelope","PROTOCOL_MISMATCH","request","answered","md","app","writtenBy","member","input","deploymentFacts","rooms","slots","query","types","syncStatus","save","outcome","history","call","log","storageLoss","structuredClone","persistence","reauthorize","draft","list","read","replace","discard","queue","presentation","write","conversation","create","send","answer","interrupt","kill","cancel","delete","chatDraft","subscribed","topic","deliver","observe","serveMdRuntime","options","stopping","AbortController","stop","abort","signal","addEventListener","once","aborted","attachments","Map","authorized","factsObservers","Set","observeFacts","add","attach","port","release","Error","undefined","subscriptions","serving","message","postMessage","detach","end","values","clear","serve","kind","get","id","loaded","set","value","error","String","event","wire","data","matching","refusal","start","replaceDeploymentFacts","endAuthorization","shell","dropGeneration"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- export type { ActionDeclaration, ActionRequest, ActionResult, Adapter, AdapterFailure, Authorization, BootstrapPage, BootstrapRequest, BootstrapResult, Capability, ContractUnavailable, ConversationAction, ConversationCards, ConversationEvent, ConversationMessage, DiscoverResult, DiscoveredRoom, Discovery, HistoryRequest, HistoryResult, HistoryRetention, HistoryRevision, MdModelIdentity, ModelRequest, MutationRequest, MutationResult, PageToken, ProviderLimit, ProviderRefusal, RefreshPage, RefreshRequest, RefreshResult, Retention, RetryableRefusal, RevokedAuthorization, RoomNotReadable, RoomVersionNotification, SelectedRooms, TransportUncertainty, TypedSelection, ViewedConversations, } from './adapter.js';
1
+ export type { AcceptedMessage, ActionDeclaration, ActionRequest, ActionResult, Adapter, AdapterFailure, Authorization, BootstrapPage, BootstrapRequest, BootstrapResult, Capability, ContractUnavailable, ConversationAction, ConversationCards, ConversationEvent, ConversationHistoryPage, ConversationHistoryRequest, ConversationMessage, ConversationStream, DiscoverResult, DiscoveredRoom, Discovery, HistoryRequest, HistoryResult, HistoryRetention, HistoryRevision, MdModelIdentity, ModelRequest, MutationRequest, MutationResult, PageToken, ProviderLimit, ProviderRefusal, RefreshPage, RefreshRequest, RefreshResult, Retention, RetryableRefusal, RevokedAuthorization, RoomNotReadable, RoomVersionNotification, SelectedRooms, TransportUncertainty, TypedSelection, } from './adapter.js';
2
2
  export type { Change, ChangeBatch, Precondition, WrittenBy } from './change.js';
3
- export type { ConversationEntry, ConversationSurface, ConversationView, GrowingText, UnsentInstruction, } from './conversation.js';
4
- export type { FileDeclaration, InstructionFile } from './file.js';
3
+ export type { ChatDraft, ChatDraftSurface, ConversationEntry, ConversationOptions, ConversationSurface, ConversationView, GrowingText, } from './conversation.js';
4
+ export type { ChatDraftFile, FileDeclaration } from './file.js';
5
5
  export type { MdType } from './collection.js';
6
6
  export type { AppRoom, AppSlot, AppSlotEntry, AppTypedSelection, ConnectionRefusal, ConnectionRefusalReason, DraftEntry, DraftSurface, HistoryQuery, MdRuntime, MdRuntimeOptions, PresentationSurface, QueueSurface, RoomTypes, SaveResult, } from './connection.js';
7
7
  export type { AcceptedOutcome, AffectedState, CallResult, QueueEntry, QueueOutcome, SubmissionOutcome, } from './outcome.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,OAAO,EACP,cAAc,EACd,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,SAAS,EACT,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,eAAe,EACf,cAAc,EACd,SAAS,EACT,aAAa,EACb,eAAe,EACf,WAAW,EACX,cAAc,EACd,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,uBAAuB,EACvB,aAAa,EACb,oBAAoB,EACpB,cAAc,EACd,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAChF,YAAY,EACV,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAClE,YAAY,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,YAAY,EACV,OAAO,EACP,OAAO,EACP,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,EACZ,SAAS,EACT,UAAU,GACX,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,eAAe,EACf,aAAa,EACb,UAAU,EACV,UAAU,EACV,YAAY,EACZ,iBAAiB,GAClB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9D,YAAY,EACV,QAAQ,EACR,aAAa,EACb,UAAU,EACV,YAAY,EACZ,WAAW,EACX,QAAQ,GACT,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EACV,oBAAoB,EACpB,aAAa,EACb,aAAa,EACb,UAAU,EACV,WAAW,EACX,eAAe,EACf,WAAW,EACX,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACrF,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,OAAO,EACP,cAAc,EACd,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,0BAA0B,EAC1B,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,SAAS,EACT,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,YAAY,EACZ,eAAe,EACf,cAAc,EACd,SAAS,EACT,aAAa,EACb,eAAe,EACf,WAAW,EACX,cAAc,EACd,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,uBAAuB,EACvB,aAAa,EACb,oBAAoB,EACpB,cAAc,GACf,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAChF,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAChE,YAAY,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,YAAY,EACV,OAAO,EACP,OAAO,EACP,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,uBAAuB,EACvB,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,EACZ,SAAS,EACT,UAAU,GACX,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,eAAe,EACf,aAAa,EACb,UAAU,EACV,UAAU,EACV,YAAY,EACZ,iBAAiB,GAClB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9D,YAAY,EACV,QAAQ,EACR,aAAa,EACb,UAAU,EACV,YAAY,EACZ,WAAW,EACX,QAAQ,GACT,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EACV,oBAAoB,EACpB,aAAa,EACb,aAAa,EACb,UAAU,EACV,WAAW,EACX,eAAe,EACf,WAAW,EACX,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACrF,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["/workspace/packages/mdruntime/src/index.ts"],"sourcesContent":["export type {\n ActionDeclaration,\n ActionRequest,\n ActionResult,\n Adapter,\n AdapterFailure,\n Authorization,\n BootstrapPage,\n BootstrapRequest,\n BootstrapResult,\n Capability,\n ContractUnavailable,\n ConversationAction,\n ConversationCards,\n ConversationEvent,\n ConversationMessage,\n DiscoverResult,\n DiscoveredRoom,\n Discovery,\n HistoryRequest,\n HistoryResult,\n HistoryRetention,\n HistoryRevision,\n MdModelIdentity,\n ModelRequest,\n MutationRequest,\n MutationResult,\n PageToken,\n ProviderLimit,\n ProviderRefusal,\n RefreshPage,\n RefreshRequest,\n RefreshResult,\n Retention,\n RetryableRefusal,\n RevokedAuthorization,\n RoomNotReadable,\n RoomVersionNotification,\n SelectedRooms,\n TransportUncertainty,\n TypedSelection,\n ViewedConversations,\n} from './adapter.js';\nexport type { Change, ChangeBatch, Precondition, WrittenBy } from './change.js';\nexport type {\n ConversationEntry,\n ConversationSurface,\n ConversationView,\n GrowingText,\n UnsentInstruction,\n} from './conversation.js';\nexport type { FileDeclaration, InstructionFile } from './file.js';\nexport type { MdType } from './collection.js';\nexport type {\n AppRoom,\n AppSlot,\n AppSlotEntry,\n AppTypedSelection,\n ConnectionRefusal,\n ConnectionRefusalReason,\n DraftEntry,\n DraftSurface,\n HistoryQuery,\n MdRuntime,\n MdRuntimeOptions,\n PresentationSurface,\n QueueSurface,\n RoomTypes,\n SaveResult,\n} from './connection.js';\nexport type {\n AcceptedOutcome,\n AffectedState,\n CallResult,\n QueueEntry,\n QueueOutcome,\n SubmissionOutcome,\n} from './outcome.js';\nexport type { SaveRefusal } from './save.js';\nexport { changeBatchIdentity } from './identity.js';\nexport { createMdRuntime } from './connection.js';\nexport type { RuntimeShell } from './durability.js';\nexport type { AttentionEntry, SyncStatus } from './status.js';\nexport type {\n Backlink,\n QueryDocument,\n QueryGroup,\n QueryOptions,\n QueryResult,\n Selector,\n} from '@agentshouse/query';\n\nexport type {\n AttachedModelBinding,\n ModelIdentity,\n ModelSnapshot,\n ModelState,\n ModelResult,\n ModelValidation,\n TypesResult,\n ValidationReceipt,\n} from './model.js';\nexport type { OperationScopes, ReplicaAdmission, ScopedRefusal } from './adapter.js';\nexport type { QueryBinding, QueryInput } from './query.js';\n"],"names":["changeBatchIdentity","createMdRuntime"],"mappings":"AA+EA,SAASA,mBAAmB,QAAQ,gBAAgB;AACpD,SAASC,eAAe,QAAQ,kBAAkB"}
1
+ {"version":3,"sources":["/workspace/packages/mdruntime/src/index.ts"],"sourcesContent":["export type {\n AcceptedMessage,\n ActionDeclaration,\n ActionRequest,\n ActionResult,\n Adapter,\n AdapterFailure,\n Authorization,\n BootstrapPage,\n BootstrapRequest,\n BootstrapResult,\n Capability,\n ContractUnavailable,\n ConversationAction,\n ConversationCards,\n ConversationEvent,\n ConversationHistoryPage,\n ConversationHistoryRequest,\n ConversationMessage,\n ConversationStream,\n DiscoverResult,\n DiscoveredRoom,\n Discovery,\n HistoryRequest,\n HistoryResult,\n HistoryRetention,\n HistoryRevision,\n MdModelIdentity,\n ModelRequest,\n MutationRequest,\n MutationResult,\n PageToken,\n ProviderLimit,\n ProviderRefusal,\n RefreshPage,\n RefreshRequest,\n RefreshResult,\n Retention,\n RetryableRefusal,\n RevokedAuthorization,\n RoomNotReadable,\n RoomVersionNotification,\n SelectedRooms,\n TransportUncertainty,\n TypedSelection,\n} from './adapter.js';\nexport type { Change, ChangeBatch, Precondition, WrittenBy } from './change.js';\nexport type {\n ChatDraft,\n ChatDraftSurface,\n ConversationEntry,\n ConversationOptions,\n ConversationSurface,\n ConversationView,\n GrowingText,\n} from './conversation.js';\nexport type { ChatDraftFile, FileDeclaration } from './file.js';\nexport type { MdType } from './collection.js';\nexport type {\n AppRoom,\n AppSlot,\n AppSlotEntry,\n AppTypedSelection,\n ConnectionRefusal,\n ConnectionRefusalReason,\n DraftEntry,\n DraftSurface,\n HistoryQuery,\n MdRuntime,\n MdRuntimeOptions,\n PresentationSurface,\n QueueSurface,\n RoomTypes,\n SaveResult,\n} from './connection.js';\nexport type {\n AcceptedOutcome,\n AffectedState,\n CallResult,\n QueueEntry,\n QueueOutcome,\n SubmissionOutcome,\n} from './outcome.js';\nexport type { SaveRefusal } from './save.js';\nexport { changeBatchIdentity } from './identity.js';\nexport { createMdRuntime } from './connection.js';\nexport type { RuntimeShell } from './durability.js';\nexport type { AttentionEntry, SyncStatus } from './status.js';\nexport type {\n Backlink,\n QueryDocument,\n QueryGroup,\n QueryOptions,\n QueryResult,\n Selector,\n} from '@agentshouse/query';\n\nexport type {\n AttachedModelBinding,\n ModelIdentity,\n ModelSnapshot,\n ModelState,\n ModelResult,\n ModelValidation,\n TypesResult,\n ValidationReceipt,\n} from './model.js';\nexport type { OperationScopes, ReplicaAdmission, ScopedRefusal } from './adapter.js';\nexport type { QueryBinding, QueryInput } from './query.js';\n"],"names":["changeBatchIdentity","createMdRuntime"],"mappings":"AAoFA,SAASA,mBAAmB,QAAQ,gBAAgB;AACpD,SAASC,eAAe,QAAQ,kBAAkB"}
package/dist/memory.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ModelResult } from './model.js';
2
- import { type ActionResult, type Adapter, type Capability, type ConversationAction, type ConversationEvent, type ConversationMessage, type DiscoveredRoom, type MdModelIdentity, type ProviderLimit, type Retention, type RoomVersionNotification } from './adapter.js';
2
+ import { type AcceptedMessage, type ActionResult, type Adapter, type Capability, type ConversationAction, type ConversationEvent, type DiscoveredRoom, type MdModelIdentity, type ProviderLimit, type Retention, type RoomVersionNotification } from './adapter.js';
3
3
  export type MemoryRoom = DiscoveredRoom & {
4
4
  model?: ModelResult;
5
5
  selectionModel?: ModelResult;
@@ -9,7 +9,7 @@ export type MemoryRoom = DiscoveredRoom & {
9
9
  };
10
10
  export type MemoryConversation = {
11
11
  conversation: string;
12
- messages?: readonly ConversationMessage[];
12
+ messages?: readonly AcceptedMessage[];
13
13
  outcomes?: Partial<Record<ConversationAction, ActionResult>>;
14
14
  };
15
15
  export type MemoryAdapterOptions = {
@@ -30,6 +30,7 @@ export type MemoryAdapter = Adapter & {
30
30
  notifyRoomVersion(notification: RoomVersionNotification): void;
31
31
  notifyConversation(event: ConversationEvent): void;
32
32
  selectedRooms(): readonly string[];
33
+ replicatedConversations(): readonly string[];
33
34
  viewedConversations(): readonly string[];
34
35
  };
35
36
  export declare function createMemoryAdapter(options?: MemoryAdapterOptions): MemoryAdapter;
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,OAAO,EAIZ,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EAExB,KAAK,cAAc,EAGnB,KAAK,eAAe,EAGpB,KAAK,aAAa,EAGlB,KAAK,SAAS,EACd,KAAK,uBAAuB,EAC7B,MAAM,cAAc,CAAC;AAkBtB,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG;IACxC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC,CAAC;CAC9D,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9B,aAAa,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,YAAY,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACrC,cAAc,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,IAAI,CAAC;IAC7C,gBAAgB,CAAC,aAAa,EAAE,SAAS,kBAAkB,EAAE,GAAG,IAAI,CAAC;IACrE,MAAM,CAAC,SAAS,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACxD,iBAAiB,CAAC,YAAY,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC/D,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnD,aAAa,IAAI,SAAS,MAAM,EAAE,CAAC;IACnC,mBAAmB,IAAI,SAAS,MAAM,EAAE,CAAC;CAC1C,CAAC;AA+BF,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CAwUrF"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAEL,KAAK,eAAe,EAEpB,KAAK,YAAY,EACjB,KAAK,OAAO,EAIZ,KAAK,UAAU,EACf,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EAGtB,KAAK,cAAc,EAGnB,KAAK,eAAe,EAGpB,KAAK,aAAa,EAGlB,KAAK,SAAS,EACd,KAAK,uBAAuB,EAC7B,MAAM,cAAc,CAAC;AAkBtB,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG;IACxC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC,CAAC;CAC9D,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9B,aAAa,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,YAAY,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACrC,cAAc,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,GAAG,IAAI,CAAC;IAC7C,gBAAgB,CAAC,aAAa,EAAE,SAAS,kBAAkB,EAAE,GAAG,IAAI,CAAC;IACrE,MAAM,CAAC,SAAS,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACxD,iBAAiB,CAAC,YAAY,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC/D,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnD,aAAa,IAAI,SAAS,MAAM,EAAE,CAAC;IACnC,uBAAuB,IAAI,SAAS,MAAM,EAAE,CAAC;IAC7C,mBAAmB,IAAI,SAAS,MAAM,EAAE,CAAC;CAC1C,CAAC;AA+BF,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CAiVrF"}
package/dist/memory.js CHANGED
@@ -50,6 +50,7 @@ export function createMemoryAdapter(options = {}) {
50
50
  const sealed = new Set();
51
51
  const historyPageSize = options.historyPageSize;
52
52
  let selected = [];
53
+ let replicated = [];
53
54
  let viewed = [];
54
55
  let issued = 0;
55
56
  function scriptConversations(entries) {
@@ -131,28 +132,21 @@ export function createMemoryAdapter(options = {}) {
131
132
  }
132
133
  };
133
134
  }
134
- function historyOf(conversation, cursor) {
135
+ function historyOf(conversation, after) {
135
136
  const messages = conversation.messages ?? [];
136
- const until = typeof cursor === 'string' ? Number(cursor) : messages.length;
137
- if (!Number.isInteger(until) || until < 0 || until > messages.length) {
138
- return {
139
- kind: 'rejected',
140
- code: 'unknown-cursor',
141
- fields: {
142
- cursor
143
- }
144
- };
145
- }
146
- const size = historyPageSize ?? messages.length;
147
- const from = Math.max(0, until - size);
137
+ const first = typeof after === 'string' ? messages.findIndex((message)=>message.position > after) : 0;
138
+ const from = first === -1 ? messages.length : first;
139
+ const page = messages.slice(from, from + (historyPageSize ?? messages.length));
140
+ const last = page.at(-1);
141
+ const result = {
142
+ messages: page,
143
+ ...last !== undefined && from + page.length < messages.length ? {
144
+ next: last.position
145
+ } : {}
146
+ };
148
147
  return {
149
148
  kind: 'action',
150
- result: {
151
- messages: messages.slice(from, until),
152
- ...from === 0 ? {} : {
153
- cursor: String(from)
154
- }
155
- }
149
+ result
156
150
  };
157
151
  }
158
152
  function conversationAction(request) {
@@ -184,7 +178,7 @@ export function createMemoryAdapter(options = {}) {
184
178
  }
185
179
  const outcome = conversation.outcomes?.[name];
186
180
  if (outcome !== undefined) return outcome;
187
- if (name === 'conversation.history') return historyOf(conversation, input.cursor);
181
+ if (name === 'conversation.history') return historyOf(conversation, input.after);
188
182
  if (name === 'conversation.send') {
189
183
  issued += 1;
190
184
  const turn = `turn-${issued}`;
@@ -253,15 +247,25 @@ export function createMemoryAdapter(options = {}) {
253
247
  sealed.add(event.message.turn);
254
248
  unsealed.delete(event.message.turn);
255
249
  }
250
+ const delivered = event.kind === 'accepted-message' || event.kind === 'gap' ? replicated : viewed;
251
+ if (!delivered.includes(event.conversation)) return;
256
252
  for (const listener of listeners)listener(event);
257
253
  },
258
254
  selectedRooms () {
259
255
  return selected;
260
256
  },
257
+ replicatedConversations () {
258
+ return replicated;
259
+ },
261
260
  viewedConversations () {
262
261
  return viewed;
263
262
  },
264
263
  conversations: {
264
+ replicate (next) {
265
+ replicated = [
266
+ ...next
267
+ ];
268
+ },
265
269
  view (next) {
266
270
  viewed = [
267
271
  ...next