| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- import NodeCache from "node-cache"
- import getFolderSize from "get-folder-size"
- import type { ClineMessage, HistoryItem } from "@roo-code/types"
- import { combineApiRequests } from "../../shared/combineApiRequests"
- 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 })
- export type TaskMetadataOptions = {
- messages: ClineMessage[]
- taskId: string
- taskNumber: number
- globalStoragePath: string
- workspace: string
- }
- export async function taskMetadata({
- messages,
- taskId,
- taskNumber,
- globalStoragePath,
- workspace,
- }: TaskMetadataOptions) {
- const taskDir = await getTaskDirectoryPath(globalStoragePath, taskId)
- // Determine message availability upfront
- const hasMessages = messages && messages.length > 0
- // Pre-calculate all values based on availability
- let timestamp: number
- let tokenUsage: ReturnType<typeof getApiMetrics>
- let taskDirSize: number
- let taskMessage: ClineMessage | undefined
- 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))))
- // 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: 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,
- cacheReads: tokenUsage.totalCacheReads,
- totalCost: tokenUsage.totalCost,
- size: taskDirSize,
- workspace,
- }
- return { historyItem, tokenUsage }
- }
|