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.
- presets/README.md +96 -0
- presets/en/_base.md +83 -0
- presets/en/_reduce.md +22 -0
- presets/en/action_items.md +52 -0
- presets/en/broad.md +53 -0
- presets/en/decisions.md +50 -0
- presets/en/digest.md +46 -0
- presets/en/highlights.md +59 -0
- presets/en/links.md +60 -0
- presets/en/multichat.md +77 -0
- presets/en/questions.md +58 -0
- presets/en/quotes.md +56 -0
- presets/en/reactions.md +66 -0
- presets/en/single_msg.md +62 -0
- presets/en/summary.md +94 -0
- presets/en/video.md +87 -0
- presets/en/website.md +93 -0
- presets/ru/_base.md +85 -0
- presets/ru/_reduce.md +22 -0
- presets/ru/action_items.md +53 -0
- presets/ru/broad.md +52 -0
- presets/ru/decisions.md +49 -0
- presets/ru/digest.md +45 -0
- presets/ru/highlights.md +57 -0
- presets/ru/links.md +58 -0
- presets/ru/multichat.md +80 -0
- presets/ru/questions.md +57 -0
- presets/ru/quotes.md +55 -0
- presets/ru/reactions.md +68 -0
- presets/ru/single_msg.md +62 -0
- presets/ru/summary.md +93 -0
- presets/ru/video.md +91 -0
- presets/ru/website.md +89 -0
- unread/__init__.py +3 -0
- unread/analyzer/__init__.py +1 -0
- unread/analyzer/chunker.py +119 -0
- unread/analyzer/commands.py +2137 -0
- unread/analyzer/filters.py +115 -0
- unread/analyzer/formatter.py +413 -0
- unread/analyzer/hasher.py +45 -0
- unread/analyzer/openai_client.py +192 -0
- unread/analyzer/pipeline.py +877 -0
- unread/analyzer/prompts.py +535 -0
- unread/ask/__init__.py +14 -0
- unread/ask/commands.py +985 -0
- unread/ask/embeddings.py +205 -0
- unread/ask/rerank.py +149 -0
- unread/ask/retrieval.py +205 -0
- unread/cli.py +2007 -0
- unread/config.py +330 -0
- unread/core/__init__.py +5 -0
- unread/core/paths.py +131 -0
- unread/core/pipeline.py +795 -0
- unread/core/run.py +85 -0
- unread/db/__init__.py +1 -0
- unread/db/repo.py +1825 -0
- unread/db/schema.sql +268 -0
- unread/enrich/__init__.py +13 -0
- unread/enrich/audio.py +208 -0
- unread/enrich/base.py +117 -0
- unread/enrich/document.py +255 -0
- unread/enrich/image.py +212 -0
- unread/enrich/link.py +280 -0
- unread/enrich/pipeline.py +222 -0
- unread/enrich/video.py +41 -0
- unread/export/__init__.py +1 -0
- unread/export/commands.py +935 -0
- unread/export/markdown.py +119 -0
- unread/i18n.py +1624 -0
- unread/interactive.py +2319 -0
- unread/media/__init__.py +1 -0
- unread/media/commands.py +317 -0
- unread/media/download.py +203 -0
- unread/models.py +108 -0
- unread/runner.py +720 -0
- unread/settings/__init__.py +6 -0
- unread/settings/commands.py +633 -0
- unread/tg/__init__.py +1 -0
- unread/tg/client.py +81 -0
- unread/tg/commands.py +1287 -0
- unread/tg/dialogs.py +238 -0
- unread/tg/folders.py +145 -0
- unread/tg/links.py +118 -0
- unread/tg/resolver.py +252 -0
- unread/tg/sync.py +375 -0
- unread/tg/topics.py +151 -0
- unread/util/__init__.py +1 -0
- unread/util/flood.py +99 -0
- unread/util/logging.py +54 -0
- unread/util/pricing.py +46 -0
- unread/util/tokens.py +31 -0
- unread/website/__init__.py +1 -0
- unread/website/commands.py +332 -0
- unread/website/content.py +438 -0
- unread/website/metadata.py +25 -0
- unread/website/paths.py +51 -0
- unread/website/urls.py +135 -0
- unread/youtube/__init__.py +1 -0
- unread/youtube/commands.py +600 -0
- unread/youtube/metadata.py +102 -0
- unread/youtube/paths.py +54 -0
- unread/youtube/transcript.py +350 -0
- unread/youtube/urls.py +86 -0
- unread-0.1.0.dist-info/METADATA +1197 -0
- unread-0.1.0.dist-info/RECORD +108 -0
- unread-0.1.0.dist-info/WHEEL +4 -0
- unread-0.1.0.dist-info/entry_points.txt +2 -0
- 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}
|
presets/en/decisions.md
ADDED
|
@@ -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}
|
presets/en/highlights.md
ADDED
|
@@ -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}
|
presets/en/multichat.md
ADDED
|
@@ -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}
|
presets/en/questions.md
ADDED
|
@@ -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}
|