Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions gemini.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,33 @@
уважно «прослухай» увесь запис від початку до кінця і не пропусти жодної важливої деталі.

Спершу подумки зроби ПОВНУ розшифровку всього мовлення, а потім на її основі склади
ДЕТАЛЬНИЙ конспект УКРАЇНСЬКОЮ у форматі Markdown:
МАКСИМАЛЬНО РОЗГОРНУТИЙ конспект УКРАЇНСЬКОЮ у форматі Markdown. Головна вимога:
пиши ДОВГО й ДЕТАЛЬНО, нічого не скорочуй і не узагальнюй до загальних фраз. Краще
надлишок деталей, ніж пропуск. Структура документа така:

# Короткий підсумок
2–4 речення про головне.
Кілька речень про головне: що це була за зустріч, які ключові теми й чим вона завершилася.
Це лишається стислим оглядом — решта документа нижче розгортає все детально.

## Перебіг обговорення
Детально, пунктами: усі теми й важливі деталі, що прозвучали (цифри, дати, імена, домовленості,
аргументи). Не скорочуй до загальних фраз — фіксуй конкретику.
ЦЕ НАЙБІЛЬША Й НАЙДЕТАЛЬНІША СЕКЦІЯ. Веди розповідь послідовно за ходом зустрічі. Розбий її
на підрозділи по темах (став підзаголовки «### Назва теми»), а всередині кожної теми
фіксуй УСЕ озвучене розгорнутими пунктами:
- хто що сказав і запропонував, які навів аргументи й контраргументи;
- усі цифри, дати, суми, терміни, назви, імена, посилання, приклади;
- хід думки й те, як учасники дійшли (чи не дійшли) згоди.
Не скорочуй до однієї фрази те, що обговорювалося довго — розпиши повноцінно.

## Ухвалені рішення
- Кожне рішення окремим пунктом.
- Кожне рішення окремим пунктом, з контекстом: що саме вирішили й чому.

## Завдання та доручення
Перелічи ВСІ завдання, доручення й домовленості, що були ОЗВУЧЕНІ, навіть згадані мимохідь.
Формат кожного пункту: «Виконавець — що зробити — до коли». Якщо щось не назване — постав «—».
Краще включити сумнівне завдання, ніж пропустити.

## Відкриті питання
- Питання, що лишилися без відповіді.
- Питання, що лишилися без відповіді або потребують подальшого з'ясування.

Якщо в записі реально немає мовлення або воно нерозбірливе — прямо так і напиши. Пиши
українською, конкретно; нічого важливого не вигадуй і не пропускай.`;
Expand Down Expand Up @@ -92,7 +100,7 @@
generationConfig: {
mediaResolution: 'MEDIA_RESOLUTION_LOW',
temperature: 0.3,
maxOutputTokens: 16384
maxOutputTokens: 65536

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Обрізана відповідь приймається як повна

Коли довга зустріч і новий детальний промпт вичерпують maxOutputTokens, Gemini може повернути частковий текст із завершенням через ліміт. Поточний шлях перевіряє лише непорожній текст, тому користувач отримає успішний конспект, який може обірватися до рішень, доручень або відкритих питань.

Fix in Cursor

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: With maxOutputTokens: 65536 and a prompt demanding maximum detail, long meetings may hit the token limit. When this happens, the Gemini API returns partial text with finishReason: "MAX_TOKENS" rather than an error. The current code only checks for non-empty text, so a truncated summary (potentially cut off before decisions, tasks, or open questions) will be saved as if it were complete. Consider checking candidate.finishReason and either warning the user or appending a note that the output was truncated.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At gemini.js, line 103:

<comment>With `maxOutputTokens: 65536` and a prompt demanding maximum detail, long meetings may hit the token limit. When this happens, the Gemini API returns partial text with `finishReason: "MAX_TOKENS"` rather than an error. The current code only checks for non-empty text, so a truncated summary (potentially cut off before decisions, tasks, or open questions) will be saved as if it were complete. Consider checking `candidate.finishReason` and either warning the user or appending a note that the output was truncated.</comment>

<file context>
@@ -92,7 +100,7 @@
             mediaResolution: 'MEDIA_RESOLUTION_LOW',
             temperature: 0.3,
-            maxOutputTokens: 16384
+            maxOutputTokens: 65536
           }
         })
</file context>

}
Comment on lines 100 to 104

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Неврахований розмір відповіді 🐞 Bug ☼ Reliability

Збільшення maxOutputTokens до 65536 (разом із промптом на «дуже довгий» конспект) може генерувати
надвеликий текст, який далі без обмежень передається в multipart-аплоад Google Doc та у локальний
фолбек через data: URL. Це може призводити до помилок збереження/завантаження або пікових витрат
памʼяті при формуванні multipart body/URL.
Agent Prompt
### Issue description
У `Gemini.geminiGenerate()` піднято `maxOutputTokens` до 65536, що разом із новим промптом «пиши довго й детально» збільшує верхню межу розміру конспекту. Далі цей текст без перевірок розміру віддається в `GDrive.createDriveDoc()` (multipart body з повним текстом) або у фолбек `chrome.downloads.download()` через `data:text/plain,...encodeURIComponent(text)`; обидва шляхи чутливі до великих payload.

### Issue Context
- Конспект генерується у service worker та зберігається в Drive як Google Doc (multipart upload).
- При помилці Drive використовується локальне завантаження через `data:` URL.

### Fix Focus Areas
- gemini.js[86-105]
- background.js[165-176]
- gdrive.js[74-97]

### Proposed fix (guidance)
1) Ввести верхню межу на розмір результату перед збереженням (наприклад, по байтах/символах) і:
   - або зменшити `maxOutputTokens` до безпечного значення,
   - або, якщо текст перевищує поріг, ділити його на частини (кілька документів/файлів) чи робити стислий варіант.
2) Зробити фолбек-завантаження без `data:` URL (щоб не інлайнити мегабайти в URL):
   - формувати `Blob([text], {type:'text/plain'})`, отримувати URL через `URL.createObjectURL(...)` і передавати його в `chrome.downloads.download`, після чого викликати `URL.revokeObjectURL`.
3) Для Drive-варіанту розглянути альтернативу multipart для великих текстів (наприклад, завантаження як `.txt/.md` через resumable upload або інший механізм, який не потребує тримати весь multipart body в памʼяті одним блоком).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

})
}
Expand Down