mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-04-28 11:30:15 +00:00
Phase 1 of Pulse AI differentiation: - Create internal/ai/context package with types, trends, builder, formatter - Implement linear regression for trend computation (growing/declining/stable/volatile) - Add storage capacity predictions (predicts days until 90% and 100%) - Wire MetricsHistory from monitor to patrol service - Update patrol to use buildEnrichedContext instead of basic summary - Update patrol prompt to reference trend indicators and predictions This gives the AI awareness of historical patterns, enabling it to: - Identify resources with concerning growth rates - Predict capacity exhaustion before it happens - Distinguish between stable high usage vs growing problems - Provide more actionable, time-aware insights All tests passing. Falls back to basic summary if metrics history unavailable.
61 lines
1.8 KiB
Go
61 lines
1.8 KiB
Go
package ai
|
|
|
|
import (
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/ai/cost"
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/config"
|
|
)
|
|
|
|
// CostPersistenceAdapter bridges ConfigPersistence to cost.Persistence.
|
|
type CostPersistenceAdapter struct {
|
|
config *config.ConfigPersistence
|
|
}
|
|
|
|
// NewCostPersistenceAdapter creates a new adapter.
|
|
func NewCostPersistenceAdapter(cfg *config.ConfigPersistence) *CostPersistenceAdapter {
|
|
return &CostPersistenceAdapter{config: cfg}
|
|
}
|
|
|
|
// SaveUsageHistory saves usage events to disk via ConfigPersistence.
|
|
func (a *CostPersistenceAdapter) SaveUsageHistory(events []cost.UsageEvent) error {
|
|
records := make([]config.AIUsageEventRecord, len(events))
|
|
for i, e := range events {
|
|
records[i] = config.AIUsageEventRecord{
|
|
Timestamp: e.Timestamp,
|
|
Provider: e.Provider,
|
|
RequestModel: e.RequestModel,
|
|
ResponseModel: e.ResponseModel,
|
|
UseCase: e.UseCase,
|
|
InputTokens: e.InputTokens,
|
|
OutputTokens: e.OutputTokens,
|
|
TargetType: e.TargetType,
|
|
TargetID: e.TargetID,
|
|
FindingID: e.FindingID,
|
|
}
|
|
}
|
|
return a.config.SaveAIUsageHistory(records)
|
|
}
|
|
|
|
// LoadUsageHistory loads usage events from disk via ConfigPersistence.
|
|
func (a *CostPersistenceAdapter) LoadUsageHistory() ([]cost.UsageEvent, error) {
|
|
data, err := a.config.LoadAIUsageHistory()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
events := make([]cost.UsageEvent, len(data.Events))
|
|
for i, r := range data.Events {
|
|
events[i] = cost.UsageEvent{
|
|
Timestamp: r.Timestamp,
|
|
Provider: r.Provider,
|
|
RequestModel: r.RequestModel,
|
|
ResponseModel: r.ResponseModel,
|
|
UseCase: r.UseCase,
|
|
InputTokens: r.InputTokens,
|
|
OutputTokens: r.OutputTokens,
|
|
TargetType: r.TargetType,
|
|
TargetID: r.TargetID,
|
|
FindingID: r.FindingID,
|
|
}
|
|
}
|
|
return events, nil
|
|
}
|