iop/apps/node/internal/adapters/cli/status/parser.go

46 lines
1.5 KiB
Go

package status
import (
"regexp"
"strings"
)
var (
// Regex patterns based on the Codex output format
// "5h limit: [████████████████████] 98% left (resets 18:38)"
// "Weekly limit: [████░░░░░░░░░░░░░░░░] 22% left (resets 10:20 on 8 May)"
dailyLimitRegex = regexp.MustCompile(`5h limit:.*?\]\s*([^%\n]+%)[^\(]*\(resets\s+([^\)]+)\)`)
weeklyLimitRegex = regexp.MustCompile(`Weekly limit:.*?\]\s*([^%\n]+%)[^\(]*\(resets\s+([^\)]+)\)`)
)
// ParseStatusOutput cleans the raw string and attempts to parse limits.
func ParseStatusOutput(raw string) (*UsageStatus, error) {
cleanRaw := cleanANSI(raw)
status := &UsageStatus{
RawOutput: cleanRaw,
}
// 1. Direct Parsing
if match := dailyLimitRegex.FindStringSubmatch(cleanRaw); len(match) > 2 {
status.DailyLimit = strings.TrimSpace(match[1])
status.DailyResetTime = strings.TrimSpace(match[2])
}
if match := weeklyLimitRegex.FindStringSubmatch(cleanRaw); len(match) > 2 {
status.WeeklyLimit = strings.TrimSpace(match[1])
status.WeeklyResetTime = strings.TrimSpace(match[2])
}
// 2. LLM Fallback (Stub)
// If direct parsing failed but we expect data, we could call an LLM here
// via a centralized LLM adapter or internal utility, passing `cleanRaw`
// to extract the schema as JSON.
return status, nil
}
// cleanANSI removes ANSI escape codes from the string.
func cleanANSI(str string) string {
ansiRegex := regexp.MustCompile(`\x1b\[[0-9;]*m`)
return ansiRegex.ReplaceAllString(str, "")
}