Skip to main content

MessageStore

@forge/monorepo


@forge/monorepo / backend/src / MessageStore

Interface: MessageStore

Defined in: backend/src/persistence/index.ts:295

Methods

append()

append(input): Promise<void>

Defined in: backend/src/persistence/index.ts:326

Record a message — #157.

The port was read-only, and both Postgres and memory adapters carried an append documented as a "test-only affordance". So there was no supported way for an application to record what the user said, and every host had to reach past the port with a cast or write raw SQL. The engine reads history from here, so something has to write to it.

Insert-only, and idempotent on the id. A message is immutable once written: editing one would rewrite history a client has already streamed and a model has already been shown. So there is deliberately no update and no delete, and a repeat of the same id is a no-op rather than an error — a retried request must not fail and must not duplicate.

Parameters

input

TenantScope & object

Returns

Promise<void>


findById()

findById(input): Promise<Message | null>

Defined in: backend/src/persistence/index.ts:296

Parameters

input

TenantScope & object

Returns

Promise<Message | null>


listByConversation()

listByConversation(input): Promise<Page<Message>>

Defined in: backend/src/persistence/index.ts:310

A page of a conversation's messages.

newestFirst exists because the port could only answer "the oldest N" — #167. That is the wrong question for a chat application, whose two real queries are "show me the start" (oldest) and "what does the model need to see" (newest). Without it, a host asking for 100 messages of a 2000-message conversation gets turns 1–100 and none of the recent ones: the assistant forgets everything that just happened, and the longer the conversation the worse it gets. Reaching the tail by paging is O(n) round trips for the query made on every single turn.

Items come back in the requested order, so a caller rendering oldest-first reverses a newest-first page. The keyset cursor flips with it, so paging is still stable under concurrent inserts in both directions.

Parameters

input

TenantScope & PageRequest & object

Returns

Promise<Page<Message>>