Small feature changes and bug fixes

This commit is contained in:
2026-02-16 13:17:08 +01:00
parent 04c9b8da1e
commit 25bcca213e
20 changed files with 2193 additions and 125 deletions

View File

@@ -180,15 +180,32 @@ final class EmailHandlerService {
let response = try await provider.chat(request: request)
let fullResponse = response.content
let promptTokens = response.usage?.promptTokens
let completionTokens = response.usage?.completionTokens
let totalTokens = response.usage.map { $0.promptTokens + $0.completionTokens }
let totalCost: Double? = nil // Calculate if provider supports it
// Calculate cost if we have pricing info
var totalCost: Double? = nil
if let usage = response.usage,
let models = try? await provider.listModels(),
let modelInfo = models.first(where: { $0.id == settings.emailHandlerModel }) {
totalCost = (Double(usage.promptTokens) * modelInfo.pricing.prompt / 1_000_000) +
(Double(usage.completionTokens) * modelInfo.pricing.completion / 1_000_000)
}
let responseTime = Date().timeIntervalSince(startTime)
log.info("AI response generated in \(String(format: "%.2f", responseTime))s")
// Generate HTML email
let htmlBody = generateHTMLEmail(aiResponse: fullResponse, originalEmail: email)
// Generate HTML email with stats
let htmlBody = generateHTMLEmail(
aiResponse: fullResponse,
originalEmail: email,
responseTime: responseTime,
promptTokens: promptTokens,
completionTokens: completionTokens,
cost: totalCost
)
// Send response email
let replySubject = email.subject.hasPrefix("Re:") ? email.subject : "Re: \(email.subject)"
@@ -275,10 +292,22 @@ final class EmailHandlerService {
// MARK: - HTML Email Generation
private func generateHTMLEmail(aiResponse: String, originalEmail: IncomingEmail) -> String {
private func generateHTMLEmail(
aiResponse: String,
originalEmail: IncomingEmail,
responseTime: TimeInterval,
promptTokens: Int?,
completionTokens: Int?,
cost: Double?
) -> String {
// Convert markdown to HTML (basic implementation)
let htmlContent = markdownToHTML(aiResponse)
// Format stats
let timeFormatted = String(format: "%.2f", responseTime)
let totalTokens = (promptTokens ?? 0) + (completionTokens ?? 0)
let costFormatted = cost.map { String(format: "$%.4f", $0) } ?? "N/A"
return """
<!DOCTYPE html>
<html>
@@ -298,12 +327,34 @@ final class EmailHandlerService {
padding: 20px;
border-radius: 8px;
}
.footer {
.stats {
margin-top: 30px;
padding-top: 20px;
padding: 15px;
background: #f8f9fa;
border-radius: 6px;
font-size: 11px;
color: #666;
}
.stats-grid {
display: grid;
grid-template-columns: auto 1fr;
gap: 8px 12px;
margin-top: 8px;
}
.stats-label {
font-weight: 600;
color: #555;
}
.stats-value {
color: #666;
}
.footer {
margin-top: 20px;
padding-top: 15px;
border-top: 1px solid #e0e0e0;
font-size: 12px;
color: #666;
text-align: center;
}
code {
background: #f5f5f5;
@@ -323,6 +374,17 @@ final class EmailHandlerService {
<div class="content">
\(htmlContent)
</div>
<div class="stats">
<div style="font-weight: 600; margin-bottom: 6px; color: #555;">📊 Processing Stats</div>
<div class="stats-grid">
<span class="stats-label">Response Time:</span>
<span class="stats-value">\(timeFormatted)s</span>
<span class="stats-label">Tokens Used:</span>
<span class="stats-value">\(totalTokens.formatted()) (\(promptTokens ?? 0) prompt + \(completionTokens ?? 0) completion)</span>
<span class="stats-label">Cost:</span>
<span class="stats-value">\(costFormatted)</span>
</div>
</div>
<div class="footer">
<p>🤖 This response was generated by AI using oAI Email Handler</p>
</div>