tripadvice

package
v0.22.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 20, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package tripadvice wraps the operator-configured AI provider to generate plain-language observations about a Rivian trip plan: charging stop summary, arrival SoC commentary, adapter warnings, and drive-mode suggestions when the plan looks sub-optimal.

Structure mirrors internal/recap: side-effect-free buildPrompt, stateless Generate, structured JSON output the SPA renders as a card below the route table.

Index

Constants

View Source
const DefaultDCFCRateUSD = 0.46

DefaultDCFCRateUSD is the per-kWh fallback used in the rare case where the cost estimator runs without a route (pre-network-table API consumers, tests). The real per-stop pricing flows through the Networks table in networks.go.

Variables

This section is empty.

Functions

This section is empty.

Types

type Context

type Context struct {
	OriginLabel      string
	DestinationLabel string
	// DriveMode is the mode the user explicitly chose, or "" for
	// "let the planner pick". Included so the model can say "you
	// planned in Conserve mode" rather than treating it as a mystery.
	DriveMode   string
	StartingSoC float64
	HasAdapter  bool
	// Weather at the origin at departure time. nil when the operator
	// has not enabled the weather feature (recap.weather_enabled).
	Weather *weather.Snapshot
	// TirePressurebars holds [FL, FR, RL, RR] in bar from the live
	// vehicle state. Zero values mean unavailable for that corner.
	TirePressureBars [4]float64
	// PackKWh is the observed battery capacity in kWh from the vehicle
	// record. 0 means unknown.
	PackKWh float64
	// TirePlacardPSI is the user-configured door-jamb cold-fill
	// pressure from the vehicle profile. 0 means unconfigured; the
	// prompt then falls back to a generic "below placard" framing
	// instead of citing a specific number.
	TirePlacardPSI float64
	// HomePricePerKWh is the user's at-home charging cost in
	// HomeCurrency (typically USD). 0 means unconfigured — the cost
	// section degrades to a pure-DCFC estimate.
	HomePricePerKWh float64
	HomeCurrency    string
	// GasPricePerGallon × distance / ComparisonMPG drives the gas-
	// equivalent chip. Both must be > 0 for the chip to render.
	GasPricePerGallon float64
	ComparisonMPG     float64
	// DCFCNetworks is the user's edited price book from Settings.
	// Pass nil or empty to use the built-in defaults from dcfcrates.
	// Per-stop rates honour each row's MemberActive flag so the
	// estimate's user-totals match what the user has actually
	// signed up for.
	DCFCNetworks []dcfcrates.NetworkOverride
}

Context bundles user-supplied labels and request parameters that would otherwise be unavailable in the plan response itself.

type CostEstimate

type CostEstimate struct {
	Currency            string  `json:"currency"`
	DCFCSpend           float64 `json:"dcfc_spend"`
	DCFCSpendUserMember float64 `json:"dcfc_spend_user_member"`
	DCFCSpendAllMember  float64 `json:"dcfc_spend_all_member"`
	HomeEquivalent      float64 `json:"home_equivalent"`
	// GasEquivalent is what the same distance would cost in an ICE
	// vehicle at the user's configured gas price + MPG. Zero when
	// either input is unset.
	GasEquivalent     float64 `json:"gas_equivalent"`
	GasPricePerGallon float64 `json:"gas_price_per_gallon"`
	GasMPG            float64 `json:"gas_mpg"`
	// DCFCRateUsed is the avg per-kWh guest rate weighted by energy.
	// Falls back to DefaultDCFCRateUSD when no waypoints priced.
	DCFCRateUsed           float64 `json:"dcfc_rate_used"`
	DCFCRateUsedUserMember float64 `json:"dcfc_rate_used_user_member"`
	DCFCRateUsedAllMember  float64 `json:"dcfc_rate_used_all_member"`
	// HomeRateUsed is the user's configured at-home rate, 0 when
	// unconfigured.
	HomeRateUsed float64 `json:"home_rate_used"`
	// Breakdown lists each priced stop. Empty when no DCFC stops
	// were on the route (all-from-home trip).
	Breakdown []CostStop `json:"breakdown,omitempty"`
}

CostEstimate is a deterministic, code-computed projection of trip cost. Four views the user cares about:

  • DCFCSpend (guest): what a walk-up driver pays.
  • DCFCSpendUserMember: cost given the user's active memberships (toggled in Settings). Equal to DCFCSpend when the user has no memberships on.
  • DCFCSpendAllMember: hypothetical "you have every plan" floor, so the strip can hint "you could save $X more by joining Tesla Supercharging Membership".
  • HomeEquivalent: every kWh at the home meter rate.

Breakdown is the per-stop attribution that drives the totals, so the SPA can show "1× EA · 1× Tesla SC · 1× RAN".

func EstimateRoute added in v0.18.85

func EstimateRoute(r *rivian.TripRoute, tc Context) CostEstimate

EstimateRoute projects DCFC spend + home-rate-equivalent for a single route. Exported so the /api/trips/plan handler can attach a cost to every route in the response without making the SPA round- trip through the AI advice endpoint just to see numbers.

type CostStop added in v0.18.83

type CostStop struct {
	NetworkSlug   string  `json:"network_slug"`
	NetworkName   string  `json:"network_name"`
	ChargerName   string  `json:"charger_name"`
	EnergyKWh     float64 `json:"energy_kwh"`
	GuestRate     float64 `json:"guest_rate"`
	UserRate      float64 `json:"user_rate"`
	AllMemberRate float64 `json:"all_member_rate"`
	MemberPlan    string  `json:"member_plan,omitempty"`
}

CostStop is one waypoint's contribution to the DCFC total.

type Parsed

type Parsed struct {
	Headline   string   `json:"headline"`
	Cost       []string `json:"cost"`
	Efficiency []string `json:"efficiency"`
	Weather    []string `json:"weather"`
	Vehicle    []string `json:"vehicle"`
}

Parsed is the structured JSON shape the model emits. Each list holds 1-3 short sentences; sections with nothing useful to say stay empty rather than emitting filler.

type Result

type Result struct {
	// Raw is the model's reply, stored and forwarded as-is.
	Raw          string
	Parsed       *Parsed
	Model        string
	InputTokens  int64
	OutputTokens int64
	// Cost is computed deterministically in Go (not by the LLM) so
	// the dollar figure is always accurate. The LLM gets the same
	// numbers in the prompt and writes the commentary around them.
	Cost CostEstimate
}

Result is what Generate returns to the handler.

func Generate

func Generate(ctx context.Context, a *ai.Analyzer, plan *rivian.TripPlan, tc Context) (Result, error)

Generate calls the AI provider with a compact trip-plan summary and returns structured advice. The context's deadline should be generous (30s+) — sit in the AI-bound route group, not the timed one.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL