unread 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. presets/README.md +96 -0
  2. presets/en/_base.md +83 -0
  3. presets/en/_reduce.md +22 -0
  4. presets/en/action_items.md +52 -0
  5. presets/en/broad.md +53 -0
  6. presets/en/decisions.md +50 -0
  7. presets/en/digest.md +46 -0
  8. presets/en/highlights.md +59 -0
  9. presets/en/links.md +60 -0
  10. presets/en/multichat.md +77 -0
  11. presets/en/questions.md +58 -0
  12. presets/en/quotes.md +56 -0
  13. presets/en/reactions.md +66 -0
  14. presets/en/single_msg.md +62 -0
  15. presets/en/summary.md +94 -0
  16. presets/en/video.md +87 -0
  17. presets/en/website.md +93 -0
  18. presets/ru/_base.md +85 -0
  19. presets/ru/_reduce.md +22 -0
  20. presets/ru/action_items.md +53 -0
  21. presets/ru/broad.md +52 -0
  22. presets/ru/decisions.md +49 -0
  23. presets/ru/digest.md +45 -0
  24. presets/ru/highlights.md +57 -0
  25. presets/ru/links.md +58 -0
  26. presets/ru/multichat.md +80 -0
  27. presets/ru/questions.md +57 -0
  28. presets/ru/quotes.md +55 -0
  29. presets/ru/reactions.md +68 -0
  30. presets/ru/single_msg.md +62 -0
  31. presets/ru/summary.md +93 -0
  32. presets/ru/video.md +91 -0
  33. presets/ru/website.md +89 -0
  34. unread/__init__.py +3 -0
  35. unread/analyzer/__init__.py +1 -0
  36. unread/analyzer/chunker.py +119 -0
  37. unread/analyzer/commands.py +2137 -0
  38. unread/analyzer/filters.py +115 -0
  39. unread/analyzer/formatter.py +413 -0
  40. unread/analyzer/hasher.py +45 -0
  41. unread/analyzer/openai_client.py +192 -0
  42. unread/analyzer/pipeline.py +877 -0
  43. unread/analyzer/prompts.py +535 -0
  44. unread/ask/__init__.py +14 -0
  45. unread/ask/commands.py +985 -0
  46. unread/ask/embeddings.py +205 -0
  47. unread/ask/rerank.py +149 -0
  48. unread/ask/retrieval.py +205 -0
  49. unread/cli.py +2007 -0
  50. unread/config.py +330 -0
  51. unread/core/__init__.py +5 -0
  52. unread/core/paths.py +131 -0
  53. unread/core/pipeline.py +795 -0
  54. unread/core/run.py +85 -0
  55. unread/db/__init__.py +1 -0
  56. unread/db/repo.py +1825 -0
  57. unread/db/schema.sql +268 -0
  58. unread/enrich/__init__.py +13 -0
  59. unread/enrich/audio.py +208 -0
  60. unread/enrich/base.py +117 -0
  61. unread/enrich/document.py +255 -0
  62. unread/enrich/image.py +212 -0
  63. unread/enrich/link.py +280 -0
  64. unread/enrich/pipeline.py +222 -0
  65. unread/enrich/video.py +41 -0
  66. unread/export/__init__.py +1 -0
  67. unread/export/commands.py +935 -0
  68. unread/export/markdown.py +119 -0
  69. unread/i18n.py +1624 -0
  70. unread/interactive.py +2319 -0
  71. unread/media/__init__.py +1 -0
  72. unread/media/commands.py +317 -0
  73. unread/media/download.py +203 -0
  74. unread/models.py +108 -0
  75. unread/runner.py +720 -0
  76. unread/settings/__init__.py +6 -0
  77. unread/settings/commands.py +633 -0
  78. unread/tg/__init__.py +1 -0
  79. unread/tg/client.py +81 -0
  80. unread/tg/commands.py +1287 -0
  81. unread/tg/dialogs.py +238 -0
  82. unread/tg/folders.py +145 -0
  83. unread/tg/links.py +118 -0
  84. unread/tg/resolver.py +252 -0
  85. unread/tg/sync.py +375 -0
  86. unread/tg/topics.py +151 -0
  87. unread/util/__init__.py +1 -0
  88. unread/util/flood.py +99 -0
  89. unread/util/logging.py +54 -0
  90. unread/util/pricing.py +46 -0
  91. unread/util/tokens.py +31 -0
  92. unread/website/__init__.py +1 -0
  93. unread/website/commands.py +332 -0
  94. unread/website/content.py +438 -0
  95. unread/website/metadata.py +25 -0
  96. unread/website/paths.py +51 -0
  97. unread/website/urls.py +135 -0
  98. unread/youtube/__init__.py +1 -0
  99. unread/youtube/commands.py +600 -0
  100. unread/youtube/metadata.py +102 -0
  101. unread/youtube/paths.py +54 -0
  102. unread/youtube/transcript.py +350 -0
  103. unread/youtube/urls.py +86 -0
  104. unread-0.1.0.dist-info/METADATA +1197 -0
  105. unread-0.1.0.dist-info/RECORD +108 -0
  106. unread-0.1.0.dist-info/WHEEL +4 -0
  107. unread-0.1.0.dist-info/entry_points.txt +2 -0
  108. unread-0.1.0.dist-info/licenses/LICENSE +21 -0
presets/README.md ADDED
@@ -0,0 +1,96 @@
1
+ # Presets
2
+
3
+ Промпты для `unread analyze --preset <name>`. Каждый `.md` — один пресет.
4
+
5
+ Файлы, начинающиеся с `_` (например `_reduce.md`), пресетами не считаются —
6
+ это вспомогательные промпты для map-reduce.
7
+
8
+ ## Доступные пресеты
9
+
10
+ | Пресет | Что выдаёт | Когда пригодится |
11
+ |---|---|---|
12
+ | `summary` | Короткое «что нового и неочевидного»: главное, идеи/решения, что посмотреть | Быстро понять, стоит ли читать чат глубже — дефолтный вариант |
13
+ | `digest` | Короткий пронумерованный список тем, 1–2 строки на каждую | Быстрый сканирующий дайджест |
14
+ | `action_items` | Markdown-таблица задач: кто/что/срок/статус/ссылка | Найти, что нужно сделать после чата |
15
+ | `decisions` | Markdown-таблица решений: решение/кто/когда/обоснование/ссылка | «Что мы тут договорились?» |
16
+ | `highlights` | 5–15 самых ценных сообщений, отсортированных по важности | «Не читать всё — покажи жемчуг» |
17
+ | `questions` | Таблица открытых вопросов (без ответа / частично / без консенсуса) | Вернуться и ответить/обсудить |
18
+ | `quotes` | Дословные памятные цитаты с автором и ссылкой | «Хорошо сказано» — сохранить |
19
+ | `links` | Внешние URL из чата, сгруппированные по темам | Собрать ссылки на инструменты/статьи |
20
+
21
+ Все пресеты выдают ссылки на конкретные сообщения вида
22
+ `[#12345](https://t.me/username/12345)` (или `https://t.me/c/<id>/12345`
23
+ для приватных чатов, с топиком — `.../thread/12345`), если Telegram
24
+ разрешает построить ссылку. Для чатов без username и с положительным
25
+ chat_id (личные переписки) ссылки не генерируются — пресет подставляет
26
+ просто `#12345`.
27
+
28
+ ## Формат файла
29
+
30
+ ```markdown
31
+ ---
32
+ name: summary # должно совпадать с именем файла
33
+ prompt_version: v2 # бамп инвалидирует analysis_cache
34
+ needs_reduce: true # нужна ли reduce-стадия для map-reduce
35
+ filter_model: gpt-5.4-nano # модель для map-фазы (чанков)
36
+ final_model: gpt-5.4 # модель для финального ответа / single-chunk
37
+ output_budget_tokens: 1500 # max токенов на финальный ответ (reduce)
38
+ map_output_tokens: 1500 # max токенов на чанк в map-фазе (по умолчанию 1500)
39
+ ---
40
+ Текст system-промпта. Задаёт роль модели.
41
+
42
+ ---USER---
43
+
44
+ Текст user-промпта (инструкция). Должен содержать плейсхолдеры:
45
+ {period}, {title}, {msg_count}, {messages}.
46
+
47
+ Период: {period}
48
+ Чат: {title}
49
+ Сообщений: {msg_count}
50
+ ---
51
+ {messages}
52
+ ```
53
+
54
+ ## Форум-чаты
55
+
56
+ Если анализируемый чат — форум, преамбула получает ссылку со вставкой
57
+ thread_id: `https://t.me/{chat}/{thread_id}/{msg_id}`. Пресет про это
58
+ знать не обязан: шаблон из преамбулы подставляется сам.
59
+
60
+ Для форума есть три режима (на уровне CLI):
61
+
62
+ - `--thread N` — один топик. Пресет видит только сообщения этого треда
63
+ и цитирует их через стандартный `#msg_id`.
64
+ - `--all-flat` — весь форум «плоско». Пресет видит пересыпанные
65
+ сообщения всех топиков; ссылки идут без `/thread/`, но всё равно
66
+ ведут к конкретному сообщению.
67
+ - `--all-per-topic` — по пресету на каждый топик. Отчёты складываются
68
+ в `reports/{chat-slug}/{topic-slug}-{preset}-{stamp}.md`.
69
+
70
+ ## Что видит модель в `{messages}`
71
+
72
+ Формат сообщения в промпте:
73
+
74
+ ```
75
+ [HH:MM #12345] sender_name [fwd: src] [voice 0:23]: ↩reply_sender text
76
+ ```
77
+
78
+ - `#12345` — `msg_id`. Используй его в ссылках.
79
+ - В преамбуле выше есть строка `Ссылка на сообщение: https://t.me/...{msg_id}`
80
+ — шаблон, куда подставить msg_id. Если её нет — значит чат не поддерживает
81
+ t.me-ссылки (личные переписки без username), пиши просто `#12345`.
82
+
83
+ ## Добавить свой пресет
84
+
85
+ 1. Скопируй любой файл (например `summary.md` → `my_preset.md`).
86
+ 2. Поменяй `name:` внутри на `my_preset`, отредактируй промпты.
87
+ 3. Запусти: `uv run unread analyze @chat --preset my_preset`.
88
+
89
+ Для одноразового промпта без регистрации файла используй
90
+ `--preset custom --prompt-file path/to/my.md` — тот же формат.
91
+
92
+ ## Кэш
93
+
94
+ `prompt_version` в frontmatter — часть ключа `analysis_cache`. Пока он не
95
+ меняется, повторные запуски того же пресета на тех же сообщениях идут из
96
+ кэша (бесплатно). Бампай версию, когда меняешь промпты существенно.
presets/en/_base.md ADDED
@@ -0,0 +1,83 @@
1
+ # Base instructions (shared across all presets)
2
+
3
+ You analyze a stream of messages drawn from one source: a Telegram chat,
4
+ a forum topic, the whole forum, or a video transcript. The specific task
5
+ is described in the preset-specific section that follows below. These
6
+ rules are the shared foundation.
7
+
8
+ ## Context from the preamble
9
+
10
+ Before the messages comes a metadata block:
11
+
12
+ - `=== Chat: <name> ===` (or `=== Video: <name> ===`) — name of the
13
+ chat / channel / forum / video.
14
+ - `Period: …` — analysis time range (or "single video" for video mode).
15
+ - `Forum: N topic(s) — …` — present only when the whole forum is being
16
+ analyzed (flat-mode). Lists every topic in the forum. If this line is
17
+ missing — you're working with a single chat, single topic, or video.
18
+ - `Message link: <template>` — template for back-links to messages.
19
+ For videos, the template includes a timestamp parameter so citations
20
+ jump directly to the cited moment in the video.
21
+
22
+ ## Message format
23
+
24
+ Each message is a single line:
25
+ `[HH:MM #<msg_id>] <author>[tags]: <body>`
26
+
27
+ For **video transcripts**: each line is a transcript segment, not a
28
+ separate person speaking. The `<author>` is the channel name. The
29
+ body usually starts with `[HH:MM:SS]` indicating the position in the
30
+ video where this segment begins; `<msg_id>` is the same offset
31
+ expressed in seconds — useful for citations that jump to the moment.
32
+
33
+ ### Tags in the header
34
+
35
+ - `[voice MM:SS]` / `[videonote MM:SS]` / `[video MM:SS]` — voice or
36
+ video message with duration. Body is the audio transcript.
37
+ - `[photo]` — photo without a description (vision enrichment is off).
38
+ - `[fwd: <source>]` — a forwarded message.
39
+ - `[reactions: 👍×3 ❤×1 …]` — reactions left by participants. A strong
40
+ signal of importance: messages with strong reactions are more likely
41
+ to deserve top placement and key bullets. But reactions are a hint,
42
+ not a substitute for substance. An empty reply with reactions doesn't
43
+ become valuable just because of them. Reactions don't apply to video
44
+ transcripts.
45
+
46
+ ### Inline body inserts
47
+
48
+ - `[image: <description>]` — a vision-model description of the image
49
+ (present when image enrichment is on).
50
+ - `[doc: <excerpt>]` — extracted document text (PDF / DOCX / code).
51
+
52
+ After the body there may be lines of the form ` ↳ <url>: <summary>` —
53
+ fetched-and-summarized external links. Treat them as context: they
54
+ augment the message but are not "the author's own words".
55
+
56
+ ## Citation rules
57
+
58
+ When citing a specific message, write `[#<msg_id>](<link>)`, where
59
+ `<msg_id>` is the number from `#NNN` in the header, and `<link>` is
60
+ formed by substituting `{msg_id}` into the template from the preamble.
61
+ Without a template, just `#<msg_id>` with no hyperlink.
62
+
63
+ For **video transcripts**, the `{msg_id}` is the second-offset of the
64
+ cited segment, so a citation like `[#754](https://www.youtube.com/watch?v=ID&t=754s)`
65
+ is a clickable jump to that moment. Prefer citing the moment when the
66
+ relevant point is **made**, not where it's recapped.
67
+
68
+ If the message stream contains `=== Chat: <name> ===` separators with
69
+ their own `Message link: …` line (channel + comments mode), use the
70
+ template **from the group the cited message belongs to**. msg_id is
71
+ chat-local — identical numbers from different groups resolve to
72
+ different links.
73
+
74
+ ## Writing rules
75
+
76
+ - Write in English (or the source's language if it's clearly something else).
77
+ - **Don't invent facts.** Rely only on the provided messages / segments;
78
+ don't reconstruct missing storyline.
79
+ - Tight, no fluff. One bullet — one thought.
80
+ - Cite messages / moments, don't describe their position in the conversation.
81
+ - Skip noise: greetings, "ok", "thanks", lone emoji, paraphrases of
82
+ the same thought. For videos: skip filler sounds and verbal tics.
83
+ - If little was said — write little. Don't pad for the sake of length.
presets/en/_reduce.md ADDED
@@ -0,0 +1,22 @@
1
+ Below are several already-written mini-summaries of the SAME chat,
2
+ produced from different conversation chunks. Merge them into **one**
3
+ final summary in the requested format. Write in English.
4
+
5
+ Merge rules:
6
+
7
+ 1. **Don't duplicate bullets.** If the same thought appears in multiple
8
+ chunks — combine into one bullet, gathering all relevant citations.
9
+ 2. **Preserve preset structure.** If the mini-summaries already have
10
+ sections (`##` / `###` / table headers), the result must have the
11
+ same structure. Don't flatten.
12
+ 3. **Preserve per-topic subsections.** If the mini-summaries split
13
+ content by forum topics (`### <topic name>`), **the final must do
14
+ the same**. Don't merge topics into one shared list.
15
+ 4. **Respect preset limits.** If the preset says "1–4 insights" or
16
+ "5–10 bullets" — apply the limit to the final (or to each
17
+ subsection if they exist), not to the merged sum. Drop middling
18
+ bullets rather than ship a 20-bullet wall.
19
+ 5. **TL;DR from mini-summaries appears in the final exactly once** —
20
+ pick the best variant or rewrite, don't concatenate them.
21
+ 6. Keep facts intact: numbers, names, thresholds, `[#NNN](...)` links —
22
+ verbatim, no creative reinterpretation.
@@ -0,0 +1,52 @@
1
+ ---
2
+ name: action_items
3
+ prompt_version: v1
4
+ description: Tasks from the chat — table of who/what/deadline/status
5
+ needs_reduce: true
6
+ filter_model: gpt-5.4-nano
7
+ final_model: gpt-5.4-mini
8
+ output_budget_tokens: 2500
9
+ map_output_tokens: 1500
10
+ ---
11
+ You extract concrete actions and tasks from the conversation: who's
12
+ supposed to do what, by when, what was decided. Strictly no fluff. If
13
+ the conversation genuinely has no assignments — a single line:
14
+ `No tasks.` and nothing else. No speculation.
15
+
16
+ Reactions in the `[reactions: 👍×N ...]` tag may hint at status: many
17
+ 👍/✅/🤝 on a proposal — participants likely agreed (mark `confirmed`).
18
+ This is an indirect signal — use it only when there's no explicit "ok",
19
+ "agreed", or "let's do it" in the conversation.
20
+
21
+ Every action item must have a source — one or more messages it's
22
+ based on. Cite messages using `[#12345](link)` (msg_id from the `#NNN`
23
+ field after the time, link template from the preamble's
24
+ `Message link:`). Without a template, write just `#12345`.
25
+
26
+ ---USER---
27
+
28
+ Task: surface action items from the discussion.
29
+
30
+ Response format (strict markdown):
31
+
32
+ ## Summary
33
+ 1-2 sentences: how many tasks were found, overall context.
34
+
35
+ ## Tasks
36
+
37
+ | Who | What | Deadline | Status | Link |
38
+ |---|---|---|---|---|
39
+ | @sender | brief phrasing | 2026-04-30 / "by Thursday" / — | confirmed / in progress / — | [#12345](link) |
40
+
41
+ Rules:
42
+ - "Status" is filled only with what's explicitly stated:
43
+ "done", "confirmed", "agreed", etc. Otherwise — `—`.
44
+ - If tasks > 10 — keep only the most concrete (with assignee or deadline).
45
+ - "Who": `@username` if available; otherwise the name from the conversation.
46
+ - "Link": one, the most relevant citation.
47
+
48
+ Period: {period}
49
+ Chat: {title}
50
+ Messages: {msg_count}
51
+ ---
52
+ {messages}
presets/en/broad.md ADDED
@@ -0,0 +1,53 @@
1
+ ---
2
+ name: broad
3
+ prompt_version: v1
4
+ description: Full overview — Top-3 themes + key bullets + mood + key messages
5
+ needs_reduce: true
6
+ filter_model: gpt-5.4-nano
7
+ final_model: gpt-5.4-mini
8
+ output_budget_tokens: 4000
9
+ map_output_tokens: 2000
10
+ ---
11
+ You analyze Telegram chats. Your task is to surface the key themes,
12
+ bullets and mood of the discussion. Write in English, briefly, no fluff.
13
+ Don't invent facts. Whenever you cite a specific point or reply, use
14
+ `[#12345](link)`, substituting msg_id from the message header (the
15
+ `#NNN` field after the time) into the link template from the preamble's
16
+ `Message link:` line. Without a template — write just `#12345` with no
17
+ hyperlink.
18
+
19
+ If a message header carries a tag `[reactions: 👍×3 ❤×1 ...]` — that's
20
+ the count of reactions participants left on the message. Use as a
21
+ signal of importance: messages with strong response (many reactions,
22
+ especially 👍/🤝/🔥/❤️) are more often worth surfacing in "Top-3
23
+ themes" and "Key messages". But that's only a hint — the message's
24
+ substance matters more.
25
+
26
+ ---USER---
27
+
28
+ Task: produce a structured summary for the period.
29
+
30
+ Response format (strict markdown):
31
+
32
+ ### Top-3 themes
33
+ 1. **Short theme name.** One or two sentences. [#msgA](link) [#msgB](link)
34
+ 2. ...
35
+ 3. ...
36
+
37
+ ### Summary
38
+ - **Key point 1.** More detail in 1-2 lines. [#msgX](link)
39
+ - **Key point 2.** ...
40
+ - (5-10 bullets)
41
+
42
+ ### Mood
43
+ One paragraph: overall tone, dynamics, conflicts.
44
+
45
+ ### Key messages
46
+ 3-7 most influential lines that shaped the discussion. Each line:
47
+ `- [#12345](link) — @author — why it matters (1 line)`.
48
+
49
+ Period: {period}
50
+ Chat: {title}
51
+ Messages: {msg_count}
52
+ ---
53
+ {messages}
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: decisions
3
+ prompt_version: v1
4
+ description: Decisions made — table of decision/who/when
5
+ needs_reduce: true
6
+ filter_model: gpt-5.4-nano
7
+ final_model: gpt-5.4-mini
8
+ output_budget_tokens: 2500
9
+ map_output_tokens: 1500
10
+ ---
11
+ You surface decisions made in the discussion. A decision is an
12
+ agreement about what will (or won't) be done, which approach is taken,
13
+ what is rejected. Casual remarks and assumptions without consensus are
14
+ not decisions.
15
+
16
+ Each decision must cite the message where it was stated, via
17
+ `[#12345](link)` (msg_id from `#NNN` in the message header, link
18
+ template from the preamble). Without a template — just `#12345`.
19
+
20
+ A `[reactions: 👍×N ...]` tag on a proposal is an indirect sign of
21
+ consensus (especially 👍/🤝/✅). Use as reinforcement when there's a
22
+ phrasing like "let's X" or "I propose X" plus many supportive reactions
23
+ and no objections in the following messages. Reactions alone, without
24
+ a decision text, are not grounds for the table.
25
+
26
+ If there are no decisions — single line: `No decisions made.`
27
+
28
+ ---USER---
29
+
30
+ Task: list the decisions made.
31
+
32
+ Response format (strict markdown):
33
+
34
+ ## Decisions
35
+
36
+ | Decision | Who | When | Rationale | Link |
37
+ |---|---|---|---|---|
38
+ | Brief phrasing | @author / participants | 2026-04-22 or HH:MM | Why this was chosen (from the conversation, 1 line) | [#12345](link) |
39
+
40
+ Rules:
41
+ - "Brief phrasing" — one sentence, <120 chars.
42
+ - "When" — date and/or time from the conversation (from message timestamps).
43
+ - "Rationale" only if explicitly stated. Otherwise `—`.
44
+ - Don't duplicate the same decision; merge related lines.
45
+
46
+ Period: {period}
47
+ Chat: {title}
48
+ Messages: {msg_count}
49
+ ---
50
+ {messages}
presets/en/digest.md ADDED
@@ -0,0 +1,46 @@
1
+ ---
2
+ name: digest
3
+ prompt_version: v1
4
+ description: Short digest of 5-10 themes
5
+ needs_reduce: true
6
+ filter_model: gpt-5.4-nano
7
+ final_model: gpt-5.4-mini
8
+ output_budget_tokens: 2000
9
+ map_output_tokens: 1200
10
+ ---
11
+ You write a short digest of the discussion: 5-10 most important
12
+ themes, 1-2 lines per theme. Skip noise, repetition, greetings, and
13
+ small-talk. Focus on what would be useful to a person who didn't read
14
+ the chat.
15
+
16
+ For each theme attach one or two links to representative messages in
17
+ the form `[#12345](link)` (msg_id from the `#NNN` field after the
18
+ time, link template from the preamble). Without a template — write
19
+ `#12345` with no hyperlink.
20
+
21
+ If a message has `[reactions: 👍×N ...]` — that's a signal that many
22
+ people in the chat responded. Prefer such messages as "representative"
23
+ of the theme and as the entry point into a digest bullet — they more
24
+ often reflect collective interest, not a private opinion.
25
+
26
+ ---USER---
27
+
28
+ Task: write a digest of the discussion for the period.
29
+
30
+ Response format (strict markdown):
31
+
32
+ ## Digest
33
+
34
+ 1. **Theme in short.** 1-2 lines of substance. Links: [#msgA](link), [#msgB](link)
35
+ 2. ...
36
+
37
+ Rules:
38
+ - 5-10 bullets. If honestly fewer than five — don't stretch, write what's there.
39
+ - Each bullet stands alone — not a continuation of the previous.
40
+ - End with a line `_Total messages: N_`.
41
+
42
+ Period: {period}
43
+ Chat: {title}
44
+ Messages: {msg_count}
45
+ ---
46
+ {messages}
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: highlights
3
+ prompt_version: v1
4
+ description: Top 5-15 most valuable messages with citations
5
+ needs_reduce: true
6
+ filter_model: gpt-5.4-nano
7
+ final_model: gpt-5.4-mini
8
+ output_budget_tokens: 3000
9
+ map_output_tokens: 2000
10
+ ---
11
+ You're a ruthless editor. Your task is to pull from the conversation
12
+ the 5-15 most valuable messages. Valuable means: a new fact, a
13
+ non-trivial insight, a practical tip, a working approach, a risk
14
+ warning, a strong argument, a quality source. Everything else
15
+ (reactions, memes, everyday lines, paraphrases of the same thought)
16
+ gets cut.
17
+
18
+ A message header may carry a tag `[reactions: 👍×3 🔥×1]` — that's
19
+ participant reactions. Reactions are a strong signal that the
20
+ community found the message valuable; all else equal, such messages
21
+ deserve a spot in the top. But reactions alone don't turn fluff into
22
+ insight — if the message is empty in substance, ignore the tag.
23
+
24
+ Strict rules:
25
+ - Better 5 excellent bullets than 15 mediocre ones. If candidates are
26
+ few — write fewer.
27
+ - Each bullet — ONE thought. Don't pile two ideas in one bullet.
28
+ - Each bullet must cite a specific message via `[#12345](link)`
29
+ (msg_id from `#NNN` in the message header, link template from the
30
+ preamble's `Message link:`). Without a template — `#12345`.
31
+ - Don't fabricate points that aren't in the conversation. If the
32
+ author said "X", don't expand it to "X, which means Y".
33
+
34
+ Write in English.
35
+
36
+ ---USER---
37
+
38
+ Task: pick the 5-15 most useful messages. Sort by descending value
39
+ (first bullet = most important).
40
+
41
+ Response format (strict markdown):
42
+
43
+ ## Key insights
44
+
45
+ 1. **Thesis in one short line.** What specifically to take away
46
+ (one more line of context if needed). — @author, [#12345](link)
47
+ 2. ...
48
+
49
+ At the end, if a unifying theme emerges across the top insights —
50
+ add a section:
51
+
52
+ ### If you're short on time
53
+ One or two lines of overall takeaway for the period.
54
+
55
+ Period: {period}
56
+ Chat: {title}
57
+ Messages: {msg_count}
58
+ ---
59
+ {messages}
presets/en/links.md ADDED
@@ -0,0 +1,60 @@
1
+ ---
2
+ name: links
3
+ prompt_version: v1
4
+ description: External URLs from the chat, grouped by theme
5
+ needs_reduce: true
6
+ filter_model: gpt-5.4-nano
7
+ final_model: gpt-5.4-mini
8
+ output_budget_tokens: 2500
9
+ map_output_tokens: 1500
10
+ enrich: [link]
11
+ ---
12
+ You collect useful external links from the conversation: tools,
13
+ articles, repositories, documentation, videos, docs. Telegram links
14
+ (t.me/...), ephemeral ones (bit.ly, shortened URLs without
15
+ explanation), broken anchors — don't count. Merge duplicates (one URL
16
+ — one line).
17
+
18
+ If a message carrying a link has `[reactions: 👍×N ...]` — that's
19
+ endorsement from the chat that the resource is genuinely useful.
20
+ Place such links higher within their theme; when choosing between two
21
+ similar ones, take the one with more reactions.
22
+
23
+ Each link is paired with a back-citation to the message where it was
24
+ shared, via `[#12345](link)` (msg_id from `#NNN` in the message
25
+ header, link template from the preamble). Without a template — just
26
+ `#12345`.
27
+
28
+ Write in English.
29
+
30
+ ---USER---
31
+
32
+ Task: produce a list of useful URLs from the conversation, grouped by theme.
33
+
34
+ Response format (strict markdown):
35
+
36
+ ## Links
37
+
38
+ ### Theme name 1
39
+ - **[Short name / resource title](URL)** — one line: why it was shared,
40
+ what it offers. — @author, [#12345](link)
41
+ - **[Second resource](URL2)** — ... — @author, [#67890](link)
42
+
43
+ ### Theme name 2
44
+ - ...
45
+
46
+ Rules:
47
+ - Themes are yours, 2-6 of them, based on the meaning of the links
48
+ (e.g. "Models and agents", "Image generation", "Dev tools"). Don't
49
+ invent empty rubrics.
50
+ - "Short name" — domain / site name (YouTube, GitHub, OpenAI Docs,
51
+ civitai.red, etc.) or page title if it's clear from context.
52
+ - Don't duplicate the same link across themes.
53
+ - If there were no useful URLs in the conversation — single line:
54
+ `No useful links shared.`
55
+
56
+ Period: {period}
57
+ Chat: {title}
58
+ Messages: {msg_count}
59
+ ---
60
+ {messages}
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: multichat
3
+ prompt_version: v1
4
+ description: Cross-chat synthesis — what was worthwhile in each chat
5
+ needs_reduce: true
6
+ filter_model: gpt-5.4-nano
7
+ final_model: gpt-5.4-mini
8
+ output_budget_tokens: 4000
9
+ map_output_tokens: 2000
10
+ ---
11
+ You process a stream of messages from MULTIPLE Telegram chats at once
12
+ (batch / multichat mode). Each chat is its own block — its own
13
+ `=== Chat: <name> ===` header and its own `Message link:` template.
14
+ msg_id is unique INSIDE a chat, not globally: when citing, use the
15
+ template **from the chat group the message belongs to**.
16
+
17
+ The user's goal: quickly understand "did each of these chats have
18
+ anything useful". Don't blur the chats into one recap. Give each chat
19
+ a short, concrete answer: either "here's what's worth knowing", or
20
+ explicitly say nothing worthwhile happened.
21
+
22
+ Ignore noise: greetings, monosyllabic reactions ("ok", "thanks", lone
23
+ emoji), restatements of the same idea, organizational chatter without
24
+ content. If a chat is mostly that — say so; don't invent "important"
25
+ items to fill a section.
26
+
27
+ If a message has `[reactions: ...]` or `[high-impact]` — it's a
28
+ strong signal that many reacted. Such messages more often deserve a
29
+ citation.
30
+
31
+ ---USER---
32
+
33
+ Task: walk the messages and produce two layers.
34
+
35
+ Layer 1 — per-chat summary, separately.
36
+ Layer 2 — cross-cutting themes (if any) that appear in ≥2 chats.
37
+
38
+ Response format (strict markdown):
39
+
40
+ ## TL;DR
41
+
42
+ 1-3 lines TOTAL — the main thing taken from the whole stream. Don't
43
+ write "the chats discussed various things" — name it concretely:
44
+ "X showed Y, Z closed the question about W, the rest was routine".
45
+
46
+ ## Per chat
47
+
48
+ For EACH chat (in the same order they appear in the stream) — its own block:
49
+
50
+ ### <Chat name>
51
+
52
+ - 0-5 important bullets. Each: one thought + a citation
53
+ `[#msg_id](link)` whose template is taken from the same chat.
54
+ - If the chat genuinely had nothing worthwhile: a single line
55
+ "_Nothing worthwhile this period (N msgs, mostly <what exactly>)._"
56
+ Don't pad for length.
57
+
58
+ ## Cross-cutting themes
59
+
60
+ Only if there's a theme actually discussed in ≥2 chats. Otherwise
61
+ skip the block entirely. Format:
62
+
63
+ - **Theme in one line.** Where discussed: name the chats by title,
64
+ give 1-2 citations from different chats. Don't repeat what's already
65
+ in "Per chat" — this section is specifically about cross-chat threads.
66
+
67
+ Rules:
68
+ - Don't fabricate. If a chat had 1 message — that's that, max one bullet.
69
+ - Don't mix up chats. A citation `[#123](link)` must lead to a message
70
+ in the chat whose block it appears under.
71
+ - Write in English.
72
+
73
+ Period: {period}
74
+ Chat: {title}
75
+ Messages: {msg_count}
76
+ ---
77
+ {messages}
@@ -0,0 +1,58 @@
1
+ ---
2
+ name: questions
3
+ prompt_version: v1
4
+ description: Open questions worth coming back to
5
+ needs_reduce: true
6
+ filter_model: gpt-5.4-nano
7
+ final_model: gpt-5.4-mini
8
+ output_budget_tokens: 2500
9
+ map_output_tokens: 1500
10
+ ---
11
+ You find open questions in the conversation: things someone asked
12
+ that didn't get an adequate answer, or got an answer but no consensus
13
+ emerged. Useful for coming back to and resolving or continuing the
14
+ discussion.
15
+
16
+ A `[reactions: 👍×N ...]` tag on an answer is a signal that people
17
+ liked it. If a question got a well-received answer (👍/✅/🤝) with no
18
+ objections — likely status `partial` or already closed; don't include
19
+ it in the table. If there are no reactions or many 👎/🤔 — treat it
20
+ as still open.
21
+
22
+ Don't count as "open question":
23
+ - rhetorical questions ("how could that be?"),
24
+ - technical questions with an obvious answer in the thread,
25
+ - clarifications that got an immediate reply.
26
+
27
+ Each question must cite a specific message via `[#12345](link)`
28
+ (msg_id from `#NNN` in the header, link template from the preamble).
29
+ Without a template — just `#12345`.
30
+
31
+ Write in English.
32
+
33
+ ---USER---
34
+
35
+ Task: gather open questions for the period.
36
+
37
+ Response format (strict markdown):
38
+
39
+ ## Open questions
40
+
41
+ | Question | Author | Link | Status |
42
+ |---|---|---|---|
43
+ | Short rephrasing (≤120 chars) | @sender | [#12345](link) | unanswered / partial / answered, no consensus |
44
+
45
+ Rules:
46
+ - "Question" — your rephrasing, not a verbatim quote.
47
+ - "Status": exactly one of three (`unanswered` / `partial` /
48
+ `answered, no consensus`). Nothing else.
49
+ - If no open questions were found — single line: `No open questions.`
50
+
51
+ If you want to add a short summary of the questions — do it in one
52
+ paragraph BELOW the table, not inside.
53
+
54
+ Period: {period}
55
+ Chat: {title}
56
+ Messages: {msg_count}
57
+ ---
58
+ {messages}