feat(ai): implement agent-redesign plan with enhanced AI travel features

Phase 1 - Configuration Infrastructure (WS1):
- Add instance-level AI env vars (VOYAGE_AI_PROVIDER, VOYAGE_AI_MODEL, VOYAGE_AI_API_KEY)
- Implement fallback chain: user key → instance key → error
- Add UserAISettings model for per-user provider/model preferences
- Enhance provider catalog with instance_configured and user_configured flags
- Optimize provider catalog to avoid N+1 queries

Phase 1 - User Preference Learning (WS2):
- Add Travel Preferences tab to Settings page
- Improve preference formatting in system prompt with emoji headers
- Add multi-user preference aggregation for shared collections

Phase 2 - Day-Level Suggestions Modal (WS3):
- Create ItinerarySuggestionModal with 3-step flow (category → filters → results)
- Add AI suggestions button to itinerary Add dropdown
- Support restaurant, activity, event, and lodging categories
- Backend endpoint POST /api/chat/suggestions/day/ with context-aware prompts

Phase 3 - Collection-Level Chat Improvements (WS4):
- Inject collection context (destination, dates) into chat system prompt
- Add quick action buttons for common queries
- Add 'Add to itinerary' button on search_places results
- Update chat UI with travel-themed branding and improved tool result cards

Phase 3 - Web Search Capability (WS5):
- Add web_search agent tool using DuckDuckGo
- Support location_context parameter for biased results
- Handle rate limiting gracefully

Phase 4 - Extensibility Architecture (WS6):
- Implement decorator-based @agent_tool registry
- Convert existing tools to use decorators
- Add GET /api/chat/capabilities/ endpoint for tool discovery
- Refactor execute_tool() to use registry pattern
This commit is contained in:
2026-03-08 23:53:14 +00:00
parent 246b081d97
commit 9d5681b1ef
22 changed files with 2358 additions and 255 deletions

View File

@@ -1,7 +1,7 @@
import { fail, redirect, type Actions } from '@sveltejs/kit';
import type { PageServerLoad } from '../$types';
const PUBLIC_SERVER_URL = process.env['PUBLIC_SERVER_URL'];
import type { ImmichIntegration, User } from '$lib/types';
import type { ImmichIntegration, User, UserRecommendationPreferenceProfile } from '$lib/types';
import { fetchCSRFToken } from '$lib/index.server';
const endpoint = PUBLIC_SERVER_URL || 'http://localhost:8000';
@@ -95,11 +95,25 @@ export const load: PageServerLoad = async (event) => {
let apiKeys: UserAPIKey[] = [];
let apiKeysConfigError: string | null = null;
let apiKeysFetch = await fetch(`${endpoint}/api/integrations/api-keys/`, {
headers: {
Cookie: `sessionid=${sessionId}`
}
});
let [apiKeysFetch, recommendationPreferencesFetch] = await Promise.all([
fetch(`${endpoint}/api/integrations/api-keys/`, {
headers: {
Cookie: `sessionid=${sessionId}`
}
}),
fetch(`${endpoint}/api/integrations/recommendation-preferences/`, {
headers: {
Cookie: `sessionid=${sessionId}`
}
})
]);
let recommendationProfile: UserRecommendationPreferenceProfile | null = null;
if (recommendationPreferencesFetch.ok) {
const recommendationProfiles =
(await recommendationPreferencesFetch.json()) as UserRecommendationPreferenceProfile[];
recommendationProfile = recommendationProfiles[0] ?? null;
}
if (apiKeysFetch.ok) {
apiKeys = (await apiKeysFetch.json()) as UserAPIKey[];
@@ -131,6 +145,7 @@ export const load: PageServerLoad = async (event) => {
stravaUserEnabled,
apiKeys,
apiKeysConfigError,
recommendationProfile,
wandererEnabled,
wandererExpired
}