const { artifacts } = require('@talkingbooklet/core'); function chatConfig(overrides = {}) { return { ingestVersion: 'v1', persona: 'companion', cacheTtl: '5m', cacheMinTokens: 4096, cacheKeepalive: false, cacheKeepaliveMax: 3, modelFullContext: 'full-model', modelHybrid: 'hybrid-model', modelSummarizeHistory: 'summary-model', modelJudge: 'judge-model', modelEmbed: 'amazon.titan-embed-text-v2:0', embedDimensions: 2, indexAlias: 'books_current', autoFullContextMaxTokens: 60000, autoPremiumPlans: ['premium'], agentMaxIterations: 4, agentMaxToolCalls: 6, agentTurnTimeoutMs: 120000, maxAnswerTokensVoice: 220, maxAnswerTokensChat: 900, maxConcurrency: 4, historyVerbatimTurns: 6, historyTokenBudget: 3000, toolResultMaxChars: 100, chapterReturnTokenCap: 1500, priceTable: { 'full-model': { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, 'hybrid-model': { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 }, }, ...overrides, }; } function sampleBook(marked = 'x'.repeat(20000)) { return { bookId: '3', marked, bookCard: { title: 'Day 3', author: null, chapters: [ { no: 2, title: 'Later', pageStart: 3, pageEnd: 4 }, { no: 1, title: 'Opening', pageStart: 1, pageEnd: 2 }, ], }, summaries: [ { chapterNo: 2, title: 'Later', pageStart: 3, pageEnd: 4, oneLine: 'later', summary: 'The later pages.' }, { chapterNo: 1, title: 'Opening', pageStart: 1, pageEnd: 2, oneLine: 'open', summary: 'The opening.' }, ], chapters: [ { chapterNo: 0, title: 'Introduction', startPage: 1, endPage: 1 }, { chapterNo: 1, title: 'Opening', startPage: 2, endPage: 2 }, { chapterNo: 3, title: 'Workshop', startPage: 3, endPage: 4 }, ], pages: [ { page: 1, text: 'Welcome' }, { page: 2, text: 'Opening body' }, { page: 3, text: 'Workshop body' }, { page: 4, text: 'Close' }, ], stats: { pageCount: 4, tokenCount: 100 }, }; } function memoryStorage(bookId = '3') { const files = { [artifacts.marked(bookId)]: 'Hello from the booklet', [artifacts.bookCard(bookId)]: JSON.stringify({ title: 'Day 3', chapters: [] }), [artifacts.summaries(bookId)]: JSON.stringify([ { chapterNo: 1, title: 'Opening', pageStart: 1, pageEnd: 1, oneLine: 'open', summary: 'Opening.' }, ]), [artifacts.stats(bookId)]: JSON.stringify({ pageCount: 1, tokenCount: 20 }), [artifacts.chapters(bookId)]: JSON.stringify({ chapters: [{ chapterNo: 1, title: 'Opening', startPage: 1, endPage: 1 }], }), [artifacts.pages(bookId)]: `${JSON.stringify({ page: 1, text: 'Hello', removedLines: [] })}\n`, }; let reads = 0; return { reads: () => reads, async getText(key) { reads += 1; if (!(key in files)) throw new Error(`missing ${key}`); return files[key]; }, async getJson(key) { return JSON.parse(await this.getText(key)); }, }; } function textStream(text, usage) { return (async function* () { yield { contentBlockDelta: { contentBlockIndex: 0, delta: { text } } }; yield { messageStop: { stopReason: 'end_turn' } }; yield { metadata: { usage } }; })(); } function usage(partial) { return { inputTokens: 1000, outputTokens: 0, cacheReadInputTokens: 0, cacheWriteInputTokens: 0, ...partial, }; } module.exports = { chatConfig, sampleBook, memoryStorage, textStream, usage };