Skip to content
Merged
Show file tree
Hide file tree
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
63 changes: 49 additions & 14 deletions src/core/task-persistence/taskMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { combineCommandSequences } from "../../shared/combineCommandSequences"
import { getApiMetrics } from "../../shared/getApiMetrics"
import { findLastIndex } from "../../shared/array"
import { getTaskDirectoryPath } from "../../utils/storage"
import { t } from "../../i18n"

const taskSizeCache = new NodeCache({ stdTTL: 30, checkperiod: 5 * 60 })

Expand All @@ -27,29 +28,63 @@ export async function taskMetadata({
workspace,
}: TaskMetadataOptions) {
const taskDir = await getTaskDirectoryPath(globalStoragePath, taskId)
const taskMessage = messages[0] // First message is always the task say.

const lastRelevantMessage =
messages[findLastIndex(messages, (m) => !(m.ask === "resume_task" || m.ask === "resume_completed_task"))]
// Determine message availability upfront
const hasMessages = messages && messages.length > 0

let taskDirSize = taskSizeCache.get<number>(taskDir)
// Pre-calculate all values based on availability
let timestamp: number
let tokenUsage: ReturnType<typeof getApiMetrics>
let taskDirSize: number
let taskMessage: ClineMessage | undefined

if (taskDirSize === undefined) {
try {
taskDirSize = await getFolderSize.loose(taskDir)
taskSizeCache.set<number>(taskDir, taskDirSize)
} catch (error) {
taskDirSize = 0
if (!hasMessages) {
// Handle no messages case
timestamp = Date.now()
tokenUsage = {
totalTokensIn: 0,
totalTokensOut: 0,
totalCacheWrites: 0,
totalCacheReads: 0,
totalCost: 0,
contextTokens: 0,
}
}
taskDirSize = 0
} else {
// Handle messages case
taskMessage = messages[0] // First message is always the task say.

const lastRelevantMessage =
messages[findLastIndex(messages, (m) => !(m.ask === "resume_task" || m.ask === "resume_completed_task"))] ||
taskMessage

timestamp = lastRelevantMessage.ts

tokenUsage = getApiMetrics(combineApiRequests(combineCommandSequences(messages.slice(1))))

const tokenUsage = getApiMetrics(combineApiRequests(combineCommandSequences(messages.slice(1))))
// Get task directory size
const cachedSize = taskSizeCache.get<number>(taskDir)

if (cachedSize === undefined) {
try {
taskDirSize = await getFolderSize.loose(taskDir)
taskSizeCache.set<number>(taskDir, taskDirSize)
} catch (error) {
taskDirSize = 0
}
} else {
taskDirSize = cachedSize
}
}

// Create historyItem once with pre-calculated values
const historyItem: HistoryItem = {
id: taskId,
number: taskNumber,
ts: lastRelevantMessage.ts,
task: taskMessage.text ?? "",
ts: timestamp,
task: hasMessages
? taskMessage!.text?.trim() || t("common:tasks.incomplete", { taskNumber })
: t("common:tasks.no_messages", { taskNumber }),
tokensIn: tokenUsage.totalTokensIn,
tokensOut: tokenUsage.totalTokensOut,
cacheWrites: tokenUsage.totalCacheWrites,
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/ca/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@
},
"tasks": {
"canceled": "Error de tasca: Ha estat aturada i cancel·lada per l'usuari.",
"deleted": "Fallada de tasca: Ha estat aturada i eliminada per l'usuari."
"deleted": "Fallada de tasca: Ha estat aturada i eliminada per l'usuari.",
"incomplete": "Tasca #{{taskNumber}} (Incompleta)",
"no_messages": "Tasca #{{taskNumber}} (Sense missatges)"
},
"storage": {
"prompt_custom_path": "Introdueix una ruta d'emmagatzematge personalitzada per a l'historial de converses o deixa-ho buit per utilitzar la ubicació predeterminada",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/de/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@
},
"tasks": {
"canceled": "Aufgabenfehler: Die Aufgabe wurde vom Benutzer gestoppt und abgebrochen.",
"deleted": "Aufgabenfehler: Die Aufgabe wurde vom Benutzer gestoppt und gelöscht."
"deleted": "Aufgabenfehler: Die Aufgabe wurde vom Benutzer gestoppt und gelöscht.",
"incomplete": "Aufgabe #{{taskNumber}} (Unvollständig)",
"no_messages": "Aufgabe #{{taskNumber}} (Keine Nachrichten)"
},
"storage": {
"prompt_custom_path": "Gib den benutzerdefinierten Speicherpfad für den Gesprächsverlauf ein, leer lassen für Standardspeicherort",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@
},
"tasks": {
"canceled": "Task error: It was stopped and canceled by the user.",
"deleted": "Task failure: It was stopped and deleted by the user."
"deleted": "Task failure: It was stopped and deleted by the user.",
"incomplete": "Task #{{taskNumber}} (Incomplete)",
"no_messages": "Task #{{taskNumber}} (No messages)"
},
"storage": {
"prompt_custom_path": "Enter custom conversation history storage path, leave empty to use default location",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/es/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@
},
"tasks": {
"canceled": "Error de tarea: Fue detenida y cancelada por el usuario.",
"deleted": "Fallo de tarea: Fue detenida y eliminada por el usuario."
"deleted": "Fallo de tarea: Fue detenida y eliminada por el usuario.",
"incomplete": "Tarea #{{taskNumber}} (Incompleta)",
"no_messages": "Tarea #{{taskNumber}} (Sin mensajes)"
},
"storage": {
"prompt_custom_path": "Ingresa la ruta de almacenamiento personalizada para el historial de conversaciones, déjala vacía para usar la ubicación predeterminada",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/fr/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@
},
"tasks": {
"canceled": "Erreur de tâche : Elle a été arrêtée et annulée par l'utilisateur.",
"deleted": "Échec de la tâche : Elle a été arrêtée et supprimée par l'utilisateur."
"deleted": "Échec de la tâche : Elle a été arrêtée et supprimée par l'utilisateur.",
"incomplete": "Tâche #{{taskNumber}} (Incomplète)",
"no_messages": "Tâche #{{taskNumber}} (Aucun message)"
},
"storage": {
"prompt_custom_path": "Entrez le chemin de stockage personnalisé pour l'historique des conversations, laissez vide pour utiliser l'emplacement par défaut",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/hi/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@
},
"tasks": {
"canceled": "टास्क त्रुटि: इसे उपयोगकर्ता द्वारा रोका और रद्द किया गया था।",
"deleted": "टास्क विफलता: इसे उपयोगकर्ता द्वारा रोका और हटाया गया था।"
"deleted": "टास्क विफलता: इसे उपयोगकर्ता द्वारा रोका और हटाया गया था।",
"incomplete": "टास्क #{{taskNumber}} (अधूरा)",
"no_messages": "टास्क #{{taskNumber}} (कोई संदेश नहीं)"
},
"storage": {
"prompt_custom_path": "वार्तालाप इतिहास के लिए कस्टम स्टोरेज पाथ दर्ज करें, डिफ़ॉल्ट स्थान का उपयोग करने के लिए खाली छोड़ दें",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/id/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@
},
"tasks": {
"canceled": "Error tugas: Dihentikan dan dibatalkan oleh pengguna.",
"deleted": "Kegagalan tugas: Dihentikan dan dihapus oleh pengguna."
"deleted": "Kegagalan tugas: Dihentikan dan dihapus oleh pengguna.",
"incomplete": "Tugas #{{taskNumber}} (Tidak lengkap)",
"no_messages": "Tugas #{{taskNumber}} (Tidak ada pesan)"
},
"storage": {
"prompt_custom_path": "Masukkan path penyimpanan riwayat percakapan kustom, biarkan kosong untuk menggunakan lokasi default",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/it/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@
},
"tasks": {
"canceled": "Errore attività: È stata interrotta e annullata dall'utente.",
"deleted": "Fallimento attività: È stata interrotta ed eliminata dall'utente."
"deleted": "Fallimento attività: È stata interrotta ed eliminata dall'utente.",
"incomplete": "Attività #{{taskNumber}} (Incompleta)",
"no_messages": "Attività #{{taskNumber}} (Nessun messaggio)"
},
"storage": {
"prompt_custom_path": "Inserisci il percorso di archiviazione personalizzato per la cronologia delle conversazioni, lascia vuoto per utilizzare la posizione predefinita",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/ja/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@
},
"tasks": {
"canceled": "タスクエラー:ユーザーによって停止およびキャンセルされました。",
"deleted": "タスク失敗:ユーザーによって停止および削除されました。"
"deleted": "タスク失敗:ユーザーによって停止および削除されました。",
"incomplete": "タスク #{{taskNumber}} (未完了)",
"no_messages": "タスク #{{taskNumber}} (メッセージなし)"
},
"storage": {
"prompt_custom_path": "会話履歴のカスタムストレージパスを入力してください。デフォルトの場所を使用する場合は空のままにしてください",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/ko/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@
},
"tasks": {
"canceled": "작업 오류: 사용자에 의해 중지 및 취소되었습니다.",
"deleted": "작업 실패: 사용자에 의해 중지 및 삭제되었습니다."
"deleted": "작업 실패: 사용자에 의해 중지 및 삭제되었습니다.",
"incomplete": "작업 #{{taskNumber}} (미완료)",
"no_messages": "작업 #{{taskNumber}} (메시지 없음)"
},
"storage": {
"prompt_custom_path": "대화 내역을 위한 사용자 지정 저장 경로를 입력하세요. 기본 위치를 사용하려면 비워두세요",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/nl/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@
},
"tasks": {
"canceled": "Taakfout: gestopt en geannuleerd door gebruiker.",
"deleted": "Taakfout: gestopt en verwijderd door gebruiker."
"deleted": "Taakfout: gestopt en verwijderd door gebruiker.",
"incomplete": "Taak #{{taskNumber}} (Onvolledig)",
"no_messages": "Taak #{{taskNumber}} (Geen berichten)"
},
"storage": {
"prompt_custom_path": "Voer een aangepast opslagpad voor gespreksgeschiedenis in, laat leeg voor standaardlocatie",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/pl/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@
},
"tasks": {
"canceled": "Błąd zadania: Zostało zatrzymane i anulowane przez użytkownika.",
"deleted": "Niepowodzenie zadania: Zostało zatrzymane i usunięte przez użytkownika."
"deleted": "Niepowodzenie zadania: Zostało zatrzymane i usunięte przez użytkownika.",
"incomplete": "Zadanie #{{taskNumber}} (Niekompletne)",
"no_messages": "Zadanie #{{taskNumber}} (Brak wiadomości)"
},
"storage": {
"prompt_custom_path": "Wprowadź niestandardową ścieżkę przechowywania dla historii konwersacji lub pozostaw puste, aby użyć lokalizacji domyślnej",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/pt-BR/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@
},
"tasks": {
"canceled": "Erro na tarefa: Foi interrompida e cancelada pelo usuário.",
"deleted": "Falha na tarefa: Foi interrompida e excluída pelo usuário."
"deleted": "Falha na tarefa: Foi interrompida e excluída pelo usuário.",
"incomplete": "Tarefa #{{taskNumber}} (Incompleta)",
"no_messages": "Tarefa #{{taskNumber}} (Sem mensagens)"
},
"storage": {
"prompt_custom_path": "Digite o caminho de armazenamento personalizado para o histórico de conversas, deixe em branco para usar o local padrão",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/ru/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@
},
"tasks": {
"canceled": "Ошибка задачи: Она была остановлена и отменена пользователем.",
"deleted": "Сбой задачи: Она была остановлена и удалена пользователем."
"deleted": "Сбой задачи: Она была остановлена и удалена пользователем.",
"incomplete": "Задача #{{taskNumber}} (Незавершенная)",
"no_messages": "Задача #{{taskNumber}} (Нет сообщений)"
},
"storage": {
"prompt_custom_path": "Введите пользовательский путь хранения истории разговоров, оставьте пустым для использования расположения по умолчанию",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/tr/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@
},
"tasks": {
"canceled": "Görev hatası: Kullanıcı tarafından durduruldu ve iptal edildi.",
"deleted": "Görev başarısız: Kullanıcı tarafından durduruldu ve silindi."
"deleted": "Görev başarısız: Kullanıcı tarafından durduruldu ve silindi.",
"incomplete": "Görev #{{taskNumber}} (Tamamlanmamış)",
"no_messages": "Görev #{{taskNumber}} (Mesaj yok)"
},
"storage": {
"prompt_custom_path": "Konuşma geçmişi için özel depolama yolunu girin, varsayılan konumu kullanmak için boş bırakın",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/vi/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@
},
"tasks": {
"canceled": "Lỗi nhiệm vụ: Nó đã bị dừng và hủy bởi người dùng.",
"deleted": "Nhiệm vụ thất bại: Nó đã bị dừng và xóa bởi người dùng."
"deleted": "Nhiệm vụ thất bại: Nó đã bị dừng và xóa bởi người dùng.",
"incomplete": "Nhiệm vụ #{{taskNumber}} (Chưa hoàn thành)",
"no_messages": "Nhiệm vụ #{{taskNumber}} (Không có tin nhắn)"
},
"storage": {
"prompt_custom_path": "Nhập đường dẫn lưu trữ tùy chỉnh cho lịch sử hội thoại, để trống để sử dụng vị trí mặc định",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/zh-CN/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@
},
"tasks": {
"canceled": "任务错误:它已被用户停止并取消。",
"deleted": "任务失败:它已被用户停止并删除。"
"deleted": "任务失败:它已被用户停止并删除。",
"incomplete": "任务 #{{taskNumber}} (未完成)",
"no_messages": "任务 #{{taskNumber}} (无消息)"
},
"storage": {
"prompt_custom_path": "输入自定义会话历史存储路径,留空以使用默认位置",
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/zh-TW/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@
},
"tasks": {
"canceled": "工作錯誤:它已被使用者停止並取消。",
"deleted": "工作失敗:它已被使用者停止並刪除。"
"deleted": "工作失敗:它已被使用者停止並刪除。",
"incomplete": "工作 #{{taskNumber}} (未完成)",
"no_messages": "工作 #{{taskNumber}} (無訊息)"
},
"storage": {
"prompt_custom_path": "輸入自訂會話歷史儲存路徑,留空以使用預設位置",
Expand Down
Loading