feat: show the conversation evidence behind each learning trajectory
Reviewers were asked to include or exclude learning trajectories while only seeing metadata — credit class, confidence, status. The decisions and their redacted context turns were already captured and stored, but no endpoint returned them, so the evidence was unreachable from the UI. Add GET /api/learning/trajectories/:id and an expandable row on the learning page that fetches on demand. Also widen SentMessageSchema to accept matrixEventId, imageOutcomeCredit and imageOutcomeAt. The learning loop added these to SentMessageRecord and they flow out of /api/messages, but the strict contract rejected them, breaking the dashboard. Enable generation with shadow mode off so eligible examples reach reply prompts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
687abab82b
commit
142378df33
25 files changed
+836
-28
No files matched your search
@@ -134,6 +134,70 @@ describe('multi-account database ownership', () => {
|
||||
expect(db.pragma('foreign_key_check')).toEqual([]);
|
||||
});
|
||||
|
||||
it('removes an account with everything it owns and leaves other accounts intact', () => {
|
||||
addAccount('t2_alice', 'alice-bot', 100);
|
||||
addAccount('t2_bob', 'bob-bot', 110);
|
||||
|
||||
for (const accountId of ['t2_alice', 't2_bob']) {
|
||||
db.prepare(`
|
||||
INSERT INTO processed_posts (account_id, id, subreddit, author, title, processed_at)
|
||||
VALUES (?, 'post-one', 'test', 'recipient', 'title', 1)
|
||||
`).run(accountId);
|
||||
db.prepare(`
|
||||
INSERT INTO sent_messages (account_id, post_id, recipient, subject, message, sent_at)
|
||||
VALUES (?, 'post-one', 'recipient', 'subject', 'message', 2)
|
||||
`).run(accountId);
|
||||
db.prepare(`
|
||||
INSERT INTO successful_messages (account_id, original_message, created_at)
|
||||
VALUES (?, 'message', 3)
|
||||
`).run(accountId);
|
||||
db.prepare(`
|
||||
INSERT INTO delivery_outbox (
|
||||
account_id, post_id, recipient, subject, message, idempotency_key,
|
||||
status, created_at, updated_at
|
||||
) VALUES (?, 'post-one', 'recipient', 'subject', 'message', 'key', 'prepared', 1, 1)
|
||||
`).run(accountId);
|
||||
db.prepare(`
|
||||
INSERT INTO activity_log (account_id, timestamp, type, message) VALUES (?, 4, 'sent', 'activity')
|
||||
`).run(accountId);
|
||||
db.prepare(`
|
||||
INSERT INTO conversation_states (account_id, conversation_id, state_json, updated_at)
|
||||
VALUES (?, 'room', '{}', 5)
|
||||
`).run(accountId);
|
||||
content.upsertConversation({
|
||||
accountId, conversationId: 'room', username: 'recipient', roomName: 'Recipient',
|
||||
payloadJson: '{}', updatedAt: 6,
|
||||
});
|
||||
content.saveSyncState({
|
||||
accountId, nextBatch: 'cursor', lastFullSyncAt: 6, lastDeltaSyncAt: 6,
|
||||
cooldownJson: null, updatedAt: 6,
|
||||
});
|
||||
}
|
||||
|
||||
expect(accounts.delete('t2_alice')).toBe(true);
|
||||
|
||||
expect(accounts.get('t2_alice')).toBeNull();
|
||||
expect(accounts.listPublic().map((account) => account.accountId)).toContain('t2_bob');
|
||||
for (const table of [
|
||||
'processed_posts', 'sent_messages', 'successful_messages', 'delivery_outbox',
|
||||
'activity_log', 'conversation_states', 'reddit_conversations', 'reddit_account_sync_state',
|
||||
]) {
|
||||
expect({ table, ...db.prepare(`SELECT COUNT(*) count FROM ${table} WHERE account_id = ?`).get('t2_alice') as object })
|
||||
.toEqual({ table, count: 0 });
|
||||
expect({ table, ...db.prepare(`SELECT COUNT(*) count FROM ${table} WHERE account_id = ?`).get('t2_bob') as object })
|
||||
.toEqual({ table, count: 1 });
|
||||
}
|
||||
expect(db.pragma('foreign_key_check')).toEqual([]);
|
||||
});
|
||||
|
||||
it('reports an unknown account as not removed and rejects a blank id', () => {
|
||||
addAccount('t2_alice', 'alice-bot', 100);
|
||||
|
||||
expect(accounts.delete('t2_missing')).toBe(false);
|
||||
expect(() => accounts.delete(' ')).toThrow(/accountId/);
|
||||
expect(accounts.get('t2_alice')).not.toBeNull();
|
||||
});
|
||||
|
||||
it('scopes legacy account-produced table uniqueness by account', () => {
|
||||
addAccount('t2_alice', 'alice-bot', 100);
|
||||
addAccount('t2_bob', 'bob-bot', 110);
|
||||
|
||||
Reference in new issue
Block a user