Commit Graph

746 Commits

Author SHA1 Message Date
alex wiesner
566077533b fix proxy csrf handling for suggestion requests 2026-03-14 12:59:35 +00:00
alex wiesner
4b3f432640 add outbound links to place suggestions 2026-03-14 12:05:55 +00:00
alex wiesner
d1704af827 fix: persist assistant tool errors and markdown 2026-03-14 11:22:14 +00:00
alex wiesner
c4d39f2812 changes 2026-03-13 20:15:22 +00:00
alex wiesner
e68c95b2dd fix: suppress duplicate assistant itinerary adds 2026-03-13 20:14:27 +00:00
a0bf8df221 fix: repair chat panel layout in panelMode
The conversations sidebar was force-shown via 'lg:flex' at large
breakpoints even when sidebarOpen was false, causing a broken split-
layout in the w-96 drawer panel (~144px left for actual chat).

Fixes:
- Sidebar no longer force-applies lg:flex in panelMode
- In panelMode the sidebar goes full-width and hides the chat area
  entirely (stacked panel pattern instead of split-column)
- Hamburger toggle is always visible in panelMode (was lg:hidden)
- Selecting a conversation or creating a new one auto-closes the
  sidebar in panelMode, returning to chat view
- Welcome screen and header title use compact sizing in panelMode
2026-03-10 21:51:05 +00:00
c9cea80875 chore: remove unused lucide-svelte dependency and format worldtravel page 2026-03-10 20:26:12 +00:00
a58acdde00 Merge branch 'feat/remove-discover-and-recommendations'
# Conflicts:
#	frontend/src/routes/collections/[id]/+page.svelte
2026-03-10 20:24:39 +00:00
9d3006ad8e feat: remove recommendations surface and backend 2026-03-10 20:20:00 +00:00
4caa1d717e feat: remove Globe Spin discover feature 2026-03-10 20:12:12 +00:00
7b4541a075 fix(collections): tighten itinerary chat panel access and state scoping 2026-03-10 20:04:15 +00:00
e6a7c83a3a feat(collections): dock travel assistant chat as persistent panel 2026-03-10 19:57:12 +00:00
635e0df0ab fix(chat): stop 429 retry spiral and add get_weather coord fallback
- search_places: detect HTTP 429 and mark retryable=False to stop the
  retry loop immediately instead of spiraling until MAX_ITERATIONS
- get_weather: extract collection coordinates (lat/lng from first
  location with coords) and retry when LLM omits required params;
  uses sync_to_async for the DB query in the async view
- AITravelChat: deduplicate context-only tools (get_trip_details,
  get_weather) in the render pipeline to prevent duplicate place cards
  from appearing when the retry loop causes multiple get_trip_details calls
- Tests: 5 new tests covering 429 non-retryable path and weather
  coord fallback; all 39 chat tests pass
2026-03-10 19:18:55 +00:00
dbabbdf9f0 fix(chat): stop retry spirals on tool failures 2026-03-10 18:05:34 +00:00
1ad9d20037 fix(chat): stabilize assistant add flow and location routing 2026-03-10 15:59:07 +00:00
49abfad192 chore: update dependencies
Backend:
- gunicorn 23.0.0 → 25.1.0
- setuptools 79.0.1 → 82.0.1
- litellm >=1.72.3 → >=1.82.1

Frontend:
- Migrate Tailwind CSS 3 → 4, daisyUI 4 → 5
  - Add @tailwindcss/vite plugin, remove autoprefixer
  - Replace tailwind.config.js with src/app.css (CSS-based config)
  - Convert custom themes (aestheticDark, catppuccinMocha, aestheticLight,
    northernLights) to daisyUI 5 CSS variable format
  - Remove daisyUI v4-only '-bordered' classes from 45 component files
    (input-bordered, select-bordered, textarea-bordered, file-input-bordered
    are removed in v5; borders are default)
- @types/node 22 → 25
- @lukulent/svelte-umami 0.0.3 → 0.0.4
- packageManager: bun@1.2.22 → bun@1.3.10

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-10 13:34:49 +00:00
c918c9ce2f fix(chat): support shared trips and polish controls 2026-03-09 22:04:53 +00:00
d8c8ecf2bd fix(chat): clean up tool output and embedded UX 2026-03-09 21:12:46 +00:00
bb54503235 fix(chat): add saved AI defaults and harden suggestions 2026-03-09 20:32:13 +00:00
21954df3ee fix(chat): improve OpenCode Zen integration and error handling
- Fetch models dynamically from OpenCode Zen API (36 models vs 5 hardcoded)
- Add function calling support check before using tools
- Add retry logic (num_retries=2) for transient failures
- Improve logging for debugging API calls and errors
- Update system prompt for multi-stop itinerary context
- Clean up unused imports in frontend components
- Remove deleted views.py (moved to views/__init__.py)
2026-03-09 16:11:14 +00:00
30fdcb078f fix: resolve three travel agent UI issues
- Connection error: wrap sync get_llm_api_key() in sync_to_async in
  stream_chat_completion() to fix SynchronousOnlyOperation raised when
  the async SSE generator calls a synchronous Django ORM function
- Models not loading: add opencode_zen handler to models endpoint
  returning its default model; fix frontend to show 'Default' instead
  of 'Loading...' indefinitely when no model list is returned
- Location in header: remove destination subtitle from Travel Assistant
  header — collection-wide chat has no single meaningful location
2026-03-09 13:34:35 +00:00
91d907204a fix(ai): critical fixes for agent-redesign - provider selection and auto-learn
Fix 1: Provider/Model Selection (Critical - unblocks LLM)
- Add /api/chat/providers/{id}/models/ endpoint to fetch available models
- Auto-select first configured provider instead of hardcoded 'openai'
- Add model dropdown populated from provider API
- Filter provider list to only show configured providers
- Show helpful error when no providers configured

Fix 2: Auto-Learn Preferences (Replaces manual input)
- Create auto_profile.py utility to infer preferences from user data
- Learn interests from Activity sport types and Location categories
- Learn trip style from Lodging types (hostel=budget, resort=luxury, etc.)
- Learn geographic preferences from VisitedRegion/VisitedCity
- Call auto-learn on every chat start (send_message)
- System prompt now indicates preferences are auto-inferred

Fix 3: Remove Manual Preference UI
- Remove travel_preferences section from Settings
- Remove preference form fields and save logic
- Remove preference fetch from server-side load
- Keep UserRecommendationPreferenceProfile type for backend use

The LLM should now work correctly:
- Users with any configured provider will have it auto-selected
- Model list is fetched dynamically from provider API
- Preferences are learned from actual travel history
2026-03-09 00:20:11 +00:00
9d5681b1ef 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
2026-03-08 23:53:14 +00:00
62578e7aa5 merge: collections AI chat integration
# Conflicts:
#	backend/server/chat/llm_client.py
#	frontend/src/routes/chat/+page.svelte
#	frontend/src/routes/settings/+page.svelte
2026-03-08 21:32:22 +00:00
d35feed98c feat(chat): add dynamic provider catalog and zen support 2026-03-08 21:29:48 +00:00
64f9fe7382 feat: embed AI travel chat in collection recommendations 2026-03-08 21:24:49 +00:00
604b52bcc7 fix(itinerary): make optimize nearest-neighbor context-aware of anchor positions
The optimize function always started nearest-neighbor from the first
array element, ignoring where the traveler actually is after preceding
anchors (flights, lodging). Now passes the preceding anchor's exit
coordinates (destination for transportation) so the algorithm picks
the spatially nearest item as the starting point.
2026-03-08 19:41:19 +00:00
73289725eb Merge branch 'feat/llm-travel-agent' into main 2026-03-08 18:54:50 +00:00
757140ec70 feat(chat): add LLM-powered travel agent with multi-provider support
Implement a full chat-based travel agent using LiteLLM for multi-provider
LLM support (OpenAI, Anthropic, Gemini, Ollama, Groq, Mistral, etc.).

Backend:
- New 'chat' Django app with ChatConversation and ChatMessage models
- Streaming SSE endpoint via StreamingHttpResponse
- 5 agent tools: search_places, list_trips, get_trip_details,
  add_to_itinerary, get_weather
- LiteLLM client wrapper with per-user API key retrieval
- System prompt with user preference context injection

Frontend:
- New /chat route with full-page chat UI (DaisyUI + Tailwind)
- Collapsible conversation sidebar with CRUD
- SSE streaming response display with tool call visualization
- Provider selector dropdown
- SSE proxy fix to stream text/event-stream without buffering
- Navbar link and i18n keys
2026-03-08 18:44:44 +00:00
6203d7ed87 fix(itinerary): fix Svelte 4 reactivity for temperature display and connector metrics
Temperature display always showed 'unavailable' because formatDayTemperature()
read dayTemperatures from closure, which Svelte 4's compiler doesn't track in
template expressions. Same issue affected getLocationConnector() reading
connectorMetricsMap from closure.

Fix: pass both state variables as explicit function parameters so they appear
in template expressions and trigger re-renders on async updates.

Also improve optimize button diagnostics with console logging and better
toast feedback when items lack coordinates.
2026-03-08 18:18:53 +00:00
d4e0ef14b8 fix(itinerary): fix route optimization reactivity and replace api key provider dropdown with AI LLM providers
- fix optimizeDayOrder() dual-update: directly set days[dayIndex].items + days before
  saveReorderedItems() so it reads the correct post-optimization order synchronously
  (Svelte 4 batches reactive statements; days wasn't updated before save read it)
- also patch collection.itinerary order values so reactive rebuild uses new order
- replace single google_maps <option> with 8 AI LLM provider options
  (anthropic, openai, gemini, ollama, groq, mistral, github_models, openrouter)
- add getApiKeyProviderLabel() helper for saved key display with google_maps fallback
- add i18n keys for all new provider labels in en.json and de.json
2026-03-08 17:45:44 +00:00
c5be09bcb9 fix(frontend): clean docs links and improve settings clarity 2026-03-08 17:21:51 +00:00
2fd11dbd26 fix: stabilize post-MVP travel-agent and itinerary workflows 2026-03-08 16:51:19 +00:00
e56170fbd4 merge: integrate mvp trip features and bun migration 2026-03-08 14:46:20 +00:00
c5939e2957 feat(frontend): apply itinerary UI and docs refinements 2026-03-08 14:42:32 +00:00
2ad814334f chore(frontend): migrate toolchain from pnpm to bun 2026-03-08 14:41:36 +00:00
8c0637c518 feat: ship MVP itinerary optimization, weather, AI key prefs, and MCP tools 2026-03-08 13:49:32 +00:00
9eb0325c7a fix(frontend): simplify collections view and restore invite access
Unify collections and shared items under a single Collections tab while keeping Archive separate, and fix card layering so menus render correctly. Restore invite discoverability by adding navbar access to /invites and add missing i18n keys to prevent raw key labels in collections/invites UI.
2026-03-08 01:29:52 +00:00
288f81f631 fix: refine itinerary lodging placement and stay metadata
Align lodging cards with itinerary flow by rendering checkout stays before the timeline and check-in stays after it, while collapsing duplicate no-location stays. Tighten compact card metadata into a concise IN/OUT panel so stay details read cleanly without visual noise.
2026-03-07 20:18:26 +00:00
2579cd46ce fix: make itinerary lodging cards compact and remove duplicate overnight summary 2026-03-07 17:47:22 +00:00
3af4f06944 feat: anchor lodging in itinerary days with boundary connectors 2026-03-07 17:28:03 +00:00
7d279883d5 fix: add directions links and stabilize connector metrics after drag 2026-03-07 15:47:41 +00:00
eb612f1cdf fix: keep itinerary connectors visible when route data is unavailable 2026-03-07 15:28:33 +00:00
cf84feb783 fix: restore itinerary connectors and refresh dependencies 2026-03-07 12:46:02 +00:00
a3d12bf4b2 feat: refine itinerary flow and add OSRM connector metrics 2026-03-07 11:54:13 +00:00
246d836459 feat: redesign itinerary flow and add catppuccin mocha theme 2026-03-07 10:20:06 +00:00
0b514a99ea feat: redesign collection UI with WanderLog-inspired card style
- CollectionCard: hero image with gradient overlay, title/date on
  image in white, glass pill status badges, compact stats footer,
  removes 'Open Details' button (entire card is clickable)
- collections page: clean white bg, underline tabs, 'New Collection'
  button in header, responsive grid starts at md breakpoint
- Fix empty dropdown for viewonly type, remove debug console.log,
  add aria-label to card container
2026-03-06 15:51:19 +00:00
04fb1dfb40 fix: replace native date inputs with custom DateInput/DateTimeInput components
Native <input type='date'> and <input type='datetime-local'> render
their display format (mm/dd/yyyy vs dd/mm/yyyy, 12h vs 24h) based on
browser/OS locale, ignoring HTML lang attributes in Firefox and
inconsistently in Chrome. The previous lang=en-GB fix was unreliable.

Create DateInput.svelte and DateTimeInput.svelte components that show
dd/mm/yyyy (and DD/MM/YYYY HH:MM for datetime) by formatting the ISO
value in JS, while delegating the actual picker to a hidden native
input triggered via showPicker(). Supported in Chrome 99+, Firefox
101+, Safari 16+ (covers all modern browsers).

Updated 8 component files across CollectionModal, ChecklistModal,
NoteModal, ImmichSelect, CollectionMap, TransportationDetails,
LodgingDetails, and LocationVisits.
2026-03-06 15:14:02 +00:00
52299c1ff2 fix: set lang=en-GB on html root to force dd/mm/yyyy and 24h inputs
The previous fix updated JavaScript date formatting functions to use
en-GB locale, but native <input type="date"> and <input type="datetime-local">
elements render their placeholder/display format based on the HTML
document's lang attribute, not JavaScript. Changing lang="en" to
lang="en-GB" on the root <html> element fixes all 15+ date/time
inputs across the app in one place.
2026-03-06 14:50:50 +00:00
d32fcb6fed chore: complete rebranding from seanmorley15 to Alex-Wiesner/voyage
Replace all seanmorley15/Voyage repo URLs, ghcr.io/seanmorley15 container
image references, seanmorley.com/sponsor and buymeacoffee links with
the new repo (github.com/Alex-Wiesner/voyage) and new GHCR images
(ghcr.io/alex-wiesner/voyage-*). Attribution to original AdventureLog
author Sean Morley is preserved.
2026-03-06 14:25:16 +00:00