Research Agents: Agents you define that answer research chats from SEC filings, your documents, and the web, citing every passage.
| 1 | // What the working line says while a company is read into the store: a sentence for the stage the |
| 2 | // work is at, with the count, rather than the count alone. Pure, so it is tested. |
| 3 | |
| 4 | const n = (value: number): string => value.toLocaleString('en-US') |
| 5 | |
| 6 | /** How far along, 0 to 10, from what is done against the whole; 0 when the whole is not known yet. */ |
| 7 | function stage(done: number, total: number): number { |
| 8 | if (total <= 0) return 0 |
| 9 | return Math.min(10, Math.floor((done / total) * 10)) |
| 10 | } |
| 11 | |
| 12 | /** The filings read so far: SEC is asked for each, it is cut by its items, and put in the store. */ |
| 13 | export function readingLine(ticker: string, done: number, total: number): string { |
| 14 | const count = `${n(done)} of ${n(total)}` |
| 15 | switch (stage(done, total)) { |
| 16 | case 0: |
| 17 | return `Knocking on SEC's door for ${ticker}: ${count} filings read` |
| 18 | case 1: |
| 19 | return `${ticker}'s first filings coming in, cut by their items: ${count}` |
| 20 | case 2: |
| 21 | return `Working through ${ticker}'s reports, one item at a time: ${count}` |
| 22 | case 3: |
| 23 | return `A third of ${ticker}'s filings are in: ${count}` |
| 24 | case 4: |
| 25 | return `${ticker}'s years going in, risk factors and all: ${count}` |
| 26 | case 5: |
| 27 | return `Halfway through ${ticker}'s filings: ${count}` |
| 28 | case 6: |
| 29 | return `Past the middle of ${ticker}'s filings: ${count}` |
| 30 | case 7: |
| 31 | return `${ticker}'s later years landing: ${count}` |
| 32 | case 8: |
| 33 | return `Nearly every ${ticker} filing is in: ${count}` |
| 34 | case 9: |
| 35 | return `The last of ${ticker}'s filings: ${count}` |
| 36 | default: |
| 37 | return `Every ${ticker} filing is read: ${count}` |
| 38 | } |
| 39 | } |
| 40 | |
| 41 | /** The passages still waiting for their embedding, out of the company's whole, which the queue works through newest first. */ |
| 42 | export function embeddingLine(ticker: string, left: number, total: number): string { |
| 43 | const togo = `${n(left)} to go` |
| 44 | switch (stage(total - left, total)) { |
| 45 | case 0: |
| 46 | return `Giving ${ticker}'s ${total > 0 ? n(total) + ' ' : ''}passages their meaning, newest first: ${togo}` |
| 47 | case 1: |
| 48 | return `${ticker}'s latest filings learning what they are about: ${togo}` |
| 49 | case 2: |
| 50 | return `Teaching the model ${ticker}'s recent years: ${togo}` |
| 51 | case 3: |
| 52 | return `A third of ${ticker}'s passages searchable by meaning: ${togo}` |
| 53 | case 4: |
| 54 | return `${ticker}'s middle years going in: ${togo}` |
| 55 | case 5: |
| 56 | return `Halfway through ${ticker}'s passages: ${togo}` |
| 57 | case 6: |
| 58 | return `${ticker}'s older filings taking their turn: ${togo}` |
| 59 | case 7: |
| 60 | return `Three quarters of ${ticker} is searchable by meaning: ${togo}` |
| 61 | case 8: |
| 62 | return `Down to ${ticker}'s last stretch: ${togo}` |
| 63 | case 9: |
| 64 | return `The last few ${ticker} passages: ${togo}` |
| 65 | default: |
| 66 | return `Every ${ticker} passage is in: ${togo}` |
| 67 | } |
| 68 | } |