Add human-led conversation learning loop

This commit is contained in:
jjbrunton committed 2026-08-11 23:04:25 +01:00
1 parent bc42c55555
commit 687abab82b
52 files changed
+2112 -53

No files matched your search

+17 -9
View File
@@ -12,6 +12,7 @@ export interface MediaExchangeChat {
existingMxcUri?: string | null,
): Promise<{ eventId: string; mxcUri: string } | null>;
sendChatMessage(roomId: string, message: string, txnId?: string): Promise<boolean>;
sendChatMessageDetailed?(roomId: string, message: string, txnId?: string): Promise<{ eventId: string } | null>;
}
export interface MediaExchangeOutboundAttribution {
@@ -125,7 +126,7 @@ export class MediaLibraryExchangeService {
if (!chosen || !chosen.enabled) {
return { kind: 'human-required', reason: 'That library image is disabled or unavailable.' };
}
send = this.repository.tryReserve(assetId, this.accountId, conversationId, incomingKey, 'generic') ?? undefined;
send = this.repository.tryReserve(assetId, this.accountId, conversationId, incomingKey, 'generic', 'human') ?? undefined;
if (!send) {
return { kind: 'human-required', reason: 'That library image has already been shared in this conversation.' };
}
@@ -205,20 +206,27 @@ export class MediaLibraryExchangeService {
if ('failure' in delivered) return delivered.failure;
send = delivered.send;
const textSent = send.matrixTextEventId
? true
: await this.chat.sendChatMessage(
conversationId,
RECIPROCAL_MESSAGE,
`rbot-library-reciprocal-${send.id}`,
);
const textReceipt = send.matrixTextEventId
? { eventId: send.matrixTextEventId }
: this.chat.sendChatMessageDetailed
? await this.chat.sendChatMessageDetailed(
conversationId,
RECIPROCAL_MESSAGE,
`rbot-library-reciprocal-${send.id}`,
)
: await this.chat.sendChatMessage(
conversationId,
RECIPROCAL_MESSAGE,
`rbot-library-reciprocal-${send.id}`,
) ? { eventId: `rbot-library-reciprocal-${send.id}` } : null;
const textSent = textReceipt !== null;
if (!textSent) {
// The image event is already confirmed. Consume the asset and surface
// a handoff rather than risking a duplicate image on a later retry.
this.repository.markSent(send.id, 'unconfirmed');
return { kind: 'human-required', reason: 'The image was sent, but the reciprocal text was not confirmed.', remoteSent: true };
}
if (!send.matrixTextEventId) this.repository.markSent(send.id, `rbot-library-reciprocal-${send.id}`);
if (!send.matrixTextEventId) this.repository.markSent(send.id, textReceipt!.eventId);
this.logger.info(`[media-library] Sent ${requestKind} asset ${asset.id} in ${conversationId}`);
return { kind: 'sent', assetId: asset.id, requestKind };
} catch (error) {