smart tdee
This commit is contained in:
+76
-21
@@ -63,6 +63,17 @@ export interface ChatStreamChunk {
|
||||
data: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface VisionDebugPayload {
|
||||
model?: string | string[];
|
||||
count?: number;
|
||||
parsed?: Record<string, unknown>;
|
||||
raw_content?: string;
|
||||
image_meta?: Record<string, unknown>;
|
||||
usage?: Record<string, unknown>;
|
||||
parse_error?: string | null;
|
||||
images?: VisionDebugPayload[];
|
||||
}
|
||||
|
||||
async function* readChatSse(response: Response): AsyncGenerator<ChatStreamChunk> {
|
||||
if (!response.ok || !response.body) {
|
||||
const detail = await response.text().catch(() => "");
|
||||
@@ -167,21 +178,36 @@ export interface WeatherHourly {
|
||||
conditions?: string;
|
||||
}
|
||||
|
||||
export interface WeatherDaily {
|
||||
date?: string;
|
||||
label?: string;
|
||||
temperature_max_c?: number | null;
|
||||
temperature_min_c?: number | null;
|
||||
precipitation_sum_mm?: number | null;
|
||||
precipitation_probability_max?: number | null;
|
||||
wind_speed_max_kmh?: number | null;
|
||||
weather_code?: number | null;
|
||||
conditions?: string;
|
||||
}
|
||||
|
||||
export interface WeatherSnapshot {
|
||||
ok: boolean;
|
||||
location?: string;
|
||||
error?: string;
|
||||
field_coverage?: { current: string[]; hourly: string[] };
|
||||
local_field_coverage?: { current: string[]; hourly: string[] };
|
||||
field_coverage?: { current: string[]; hourly: string[]; daily: string[] };
|
||||
local_field_coverage?: { current: string[]; hourly: string[]; daily: string[] };
|
||||
data_source?: string;
|
||||
merged_fields?: string[];
|
||||
sync_hint?: string;
|
||||
current?: WeatherCurrent;
|
||||
hourly?: WeatherHourly[];
|
||||
daily?: WeatherDaily[];
|
||||
}
|
||||
|
||||
export interface WeatherDashboard {
|
||||
weather: WeatherSnapshot;
|
||||
rain_summary: string;
|
||||
daily_summary: string;
|
||||
assistant_context: string;
|
||||
cache: {
|
||||
has_data: boolean;
|
||||
@@ -191,6 +217,7 @@ export interface WeatherDashboard {
|
||||
ttl_sec: number;
|
||||
expires_in_sec: number | null;
|
||||
source?: string;
|
||||
merged_fields?: string[];
|
||||
};
|
||||
config: {
|
||||
location: string;
|
||||
@@ -204,10 +231,12 @@ export interface WeatherDashboard {
|
||||
available_fields: {
|
||||
current: string[];
|
||||
hourly: string[];
|
||||
daily: string[];
|
||||
};
|
||||
field_coverage: { current: string[]; hourly: string[] };
|
||||
local_field_coverage: { current: string[]; hourly: string[] };
|
||||
field_coverage: { current: string[]; hourly: string[]; daily: string[] };
|
||||
local_field_coverage: { current: string[]; hourly: string[]; daily: string[] };
|
||||
data_source: string;
|
||||
merged_fields: string[];
|
||||
sync_hint: string;
|
||||
recommended_sync: { domains: string; variables: string };
|
||||
assistant_tools: Record<string, string>;
|
||||
@@ -254,15 +283,14 @@ export interface MemoryFact {
|
||||
}
|
||||
|
||||
|
||||
export interface FitnessActivityBonus {
|
||||
export interface FitnessTdeeBreakdown {
|
||||
bmr: number;
|
||||
neat_kcal: number;
|
||||
steps_kcal: number;
|
||||
workout_kcal: number;
|
||||
tdee: number;
|
||||
calorie_target: number;
|
||||
steps: number;
|
||||
steps_baseline: number;
|
||||
steps_bonus_kcal: number;
|
||||
workout_active_kcal: number;
|
||||
workout_baseline_kcal: number;
|
||||
workout_bonus_kcal: number;
|
||||
total_bonus_kcal: number;
|
||||
scale_factor: number;
|
||||
}
|
||||
|
||||
export interface FitnessTargets {
|
||||
@@ -297,6 +325,9 @@ export interface FitnessComputed {
|
||||
bmr: number;
|
||||
tdee: number;
|
||||
bmi: number;
|
||||
neat_kcal?: number;
|
||||
steps_kcal?: number;
|
||||
workout_kcal?: number;
|
||||
}
|
||||
|
||||
export interface FitnessProfile {
|
||||
@@ -304,12 +335,9 @@ export interface FitnessProfile {
|
||||
age?: number;
|
||||
height_cm?: number;
|
||||
weight_kg?: number;
|
||||
activity_level?: string;
|
||||
goal?: string;
|
||||
target_weight_kg?: number | null;
|
||||
weekly_workouts?: number;
|
||||
baseline_steps?: number | null;
|
||||
baseline_workout_kcal?: number | null;
|
||||
neat_base_kcal?: number;
|
||||
calorie_target?: number;
|
||||
protein_g?: number;
|
||||
fat_g?: number;
|
||||
@@ -359,8 +387,7 @@ export interface FitnessDailySummary {
|
||||
steps?: number;
|
||||
};
|
||||
targets: FitnessTargets;
|
||||
targets_base?: FitnessTargets;
|
||||
activity?: FitnessActivityBonus;
|
||||
tdee_breakdown?: FitnessTdeeBreakdown;
|
||||
steps?: StepLogItem[];
|
||||
steps_total?: number;
|
||||
meals: FoodLogItem[];
|
||||
@@ -407,7 +434,7 @@ export interface FitnessDayOverview {
|
||||
has_data: boolean;
|
||||
totals: FitnessDailySummary["totals"];
|
||||
targets: FitnessDailySummary["targets"];
|
||||
targets_base?: FitnessTargets;
|
||||
tdee_breakdown?: FitnessTdeeBreakdown;
|
||||
meal_count: number;
|
||||
workout_count: number;
|
||||
}
|
||||
@@ -579,6 +606,31 @@ export const api = {
|
||||
yield* readChatSse(response);
|
||||
},
|
||||
|
||||
sendMessageWithImage: async function* (sessionId: number, content: string, file: File) {
|
||||
yield* api.sendMessageWithImages(sessionId, content, [file]);
|
||||
},
|
||||
|
||||
sendMessageWithImages: async function* (sessionId: number, content: string, files: File[]) {
|
||||
const form = new FormData();
|
||||
form.append("content", content);
|
||||
for (const file of files) {
|
||||
form.append("images", file);
|
||||
}
|
||||
|
||||
const response = await fetch(`${API_BASE}/api/v1/chat/sessions/${sessionId}/messages`, {
|
||||
method: "POST",
|
||||
headers: authHeaders(),
|
||||
body: form,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const detail = await response.text().catch(() => "");
|
||||
throw new Error(detail || `Ошибка отправки (${response.status})`);
|
||||
}
|
||||
|
||||
yield* readChatSse(response);
|
||||
},
|
||||
|
||||
streamGeneration: async function* (sessionId: number) {
|
||||
const response = await fetch(
|
||||
`${API_BASE}/api/v1/chat/sessions/${sessionId}/generation/stream`,
|
||||
@@ -634,8 +686,10 @@ export const api = {
|
||||
{ method: "POST" }
|
||||
),
|
||||
|
||||
weatherDashboard: (hoursAhead = 12) =>
|
||||
request<WeatherDashboard>(`/api/v1/homelab/weather?hours_ahead=${hoursAhead}`),
|
||||
weatherDashboard: (hoursAhead = 12, daysAhead = 7) =>
|
||||
request<WeatherDashboard>(
|
||||
`/api/v1/homelab/weather?hours_ahead=${hoursAhead}&days_ahead=${daysAhead}`,
|
||||
),
|
||||
|
||||
getCharacter: () => request<CharacterCardV2>("/api/v1/character"),
|
||||
|
||||
@@ -914,6 +968,7 @@ export interface RemindersCalendar {
|
||||
export interface AssistantSettings {
|
||||
openrouter_model: string;
|
||||
memory_extract_model: string;
|
||||
openrouter_vision_model: string;
|
||||
openrouter_reasoning_effort: string;
|
||||
rag_enabled: boolean;
|
||||
rag_top_k: number;
|
||||
|
||||
Reference in New Issue
Block a user