From 3457fd6478b5318d9e99b207f8690d38827517c8 Mon Sep 17 00:00:00 2001 From: cogwheel0 <172976095+cogwheel0@users.noreply.github.com> Date: Tue, 16 Sep 2025 12:58:02 +0530 Subject: [PATCH] chore: update AGENTS.md --- AGENTS.md | 159 +++----------------- docs/flutter_vs_openwebui_comparison.md | 190 ------------------------ 2 files changed, 21 insertions(+), 328 deletions(-) delete mode 100644 docs/flutter_vs_openwebui_comparison.md diff --git a/AGENTS.md b/AGENTS.md index 5965135..d5fb083 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,143 +1,26 @@ -# AGENTS.md +# Repository Guidelines -Guidelines for AI coding agents working in this repository. Follow these guardrails to make safe, minimal, and effective changes. +## Project Structure & Module Organization +- `lib/` hosts Flutter code: `core/` for services, `features/` for screens and flows, `shared/` for reusable UI, `l10n/` for generated localization, and `main.dart` as the bootstrap entry. +- `assets/` contains bundled media referenced in `pubspec.yaml`; platform bits live inside `android/` and `ios/`. Release collateral is under `fastlane/`, while helper scripts sit in `scripts/`. -## Purpose +## Build, Test, and Development Commands +- `flutter pub get` installs pub dependencies after manifest edits. +- `flutter pub run build_runner build --delete-conflicting-outputs` regenerates serializers and other codegen output. +- `flutter run -d ` launches a debug build against an emulator or physical device (`-d ios`, `-d android`). +- `flutter analyze` executes static analysis checks; fix warnings before committing. +- `flutter build apk --release`, `flutter build appbundle --release`, and `flutter build ios --release` assemble store packages. +- `./scripts/release.sh` orchestrates the tagged release workflow once CI succeeds. -- Define how agents contribute changes safely to this Flutter mobile app. -- Provide project‑specific commands, structure, and do/don’t rules. -- Ensure consistency with existing code style and workflows. +## Coding Style & Naming Conventions +- Use Flutter defaults: two-space indentation, `lowerCamelCase` for members, `UpperCamelCase` for types, and snake_case filenames across `lib/` and `test/`. +- Format code with `dart format .` and rely on `flutter analyze` to enforce `package:flutter_lints` (see `analysis_options.yaml`). Avoid `print`; prefer injected loggers or platform channels. -## Guardrails - -- Minimal, targeted changes only; don’t refactor broadly without a clear reason. -- Don’t edit generated files or vendored sources (see “Do Not Edit” list). -- Don’t introduce new dependencies without a clear justification. -- Don’t commit secrets, tokens, or credentials. Use env/config only. -- Don’t change licensing headers or LICENSE. -- Prefer surgical fixes over sweeping rewrites; match existing patterns. -- Update or add documentation when behavior changes. - -## Project Overview - -- Stack: Flutter/Dart mobile app for interacting with Open‑WebUI. -- Notable packages: `flutter_riverpod`, `dio`, `freezed`, `json_serializable`, `flutter_secure_storage`. -- Codegen: `build_runner` (freezed/json_serializable) and Flutter gen‑l10n. -- State management: Riverpod. - -## Key Commands - -Run from repository root. - -```bash -# Install deps -flutter pub get - -# Generate code (freezed/json_serializable) -flutter pub run build_runner build --delete-conflicting-outputs - -# Localization codegen (auto during run/build) -flutter gen-l10n - -# Analyze & format -flutter analyze -dart format . - -# Run app (pick a platform) -flutter run -d ios -flutter run -d android - -# Build release artifacts -flutter build apk --release -flutter build appbundle --release -flutter build ios --release -``` - -## Repository Structure (high‑level) - -``` -lib/ - core/ # models, services, providers, utils - features/ # feature‑scoped UI/logic (auth, chat, server, settings) - l10n/ # ARB + generated localization - shared/ # shared widgets, theme, utils -``` - -Follow existing folder conventions when adding code. Prefer feature folders for new UI or logic. - -## Code Generation - -- Freezed/JSON: run `flutter pub run build_runner build --delete-conflicting-outputs` after changes to models/DTOs. -- Localization: edit ARB files and run `flutter gen-l10n` (or `flutter run`). See `docs/localization.md`. - -## Do Not Edit (Generated/Vendored) - -- `build/` -- `lib/l10n/app_localizations*.dart` (generated by gen‑l10n) -- `openwebui-src/` (vendored upstream; only update by syncing from upstream, not ad‑hoc edits) -- Any other generated files created by build tools - -If a change appears necessary to a generated file, modify its source (e.g., ARB or model) and regenerate. - -## Patterns & Style - -- Riverpod: prefer providers/notifiers consistent with existing usage. -- Networking: use the shared `Dio` provider and interceptors if present. -- Models: use `freezed`/`json_serializable` patterns matching current models. -- UI: reuse shared widgets where possible; keep styling consistent. -- Null safety: follow strict null‑safety conventions already in the codebase. -- Lints: keep `flutter analyze` clean; fix warnings you introduce. - -## Validation Checklist (before opening a PR) - -- Ran `flutter pub get` and codegen commands. -- App compiles and runs on at least one target (`ios` or `android`). -- `flutter analyze` passes with no new issues. -- Updated docs/README if behavior or setup changed. -- No changes to generated/vendored files. -- No secrets, tokens, or credentials added to the repo. - -## Localization - -- Add/edit strings in `lib/l10n/app_en.arb`; mirror in other `app_.arb` as needed. -- Provide `@key` metadata with descriptions and placeholders. -- Don’t edit `app_localizations*.dart` directly. See `docs/localization.md`. - -## Releases - -- Primary release flow is CI‑driven. A helper exists at `scripts/release.sh`. -- Don’t bump versions casually. If required, coordinate and follow `scripts/release.sh` prompts. - -## When Adding Dependencies - -- Justify why it’s needed and whether an existing dependency covers the use case. -- Prefer well‑maintained packages with strong adoption. -- Keep `pubspec.yaml` tidy; avoid overlapping functionality. - -## When Touching Platform Code - -- iOS: ensure entitlements, Info.plist keys, and signing remain valid. -- Android: check permissions, minSdk (23+), and manifest changes. -- Test basic run on the affected platform. - -## Security & Privacy - -- Credentials must use platform secure storage (`flutter_secure_storage`). -- Avoid logging sensitive information. -- Network calls should respect the configured Open‑WebUI endpoint and headers. - -## PR Expectations - -- Keep diffs focused; include a short rationale in the PR description. -- Link related issues or TODOs when possible. -- Include screenshots or short clips for UI changes. - -## If You’re Unsure - -- Prefer creating a small draft PR or documenting assumptions inline with the PR description rather than pushing risky changes. -- When in doubt about ownership or expectations, open a GitHub issue first. - ---- - -Thank you for keeping changes safe, minimal, and consistent. This helps maintain velocity and quality for the Conduit app. +## Commit & Pull Request Guidelines +- Follow Conventional Commits (`feat:`, `fix:`, `chore:`, `refactor:`) as in existing history. Keep subject lines ≤72 characters and add context in the body when behavior changes. +- Pull requests should outline the change, link issues, and list manual validation steps. Attach screenshots or recordings for UI updates. +- Rebase onto `main`, rerun codegen, and ensure CI is green before requesting review. Delete obsolete assets and localization strings in the same patch when touched. +## Localization & Configuration Notes +- Update generated delegates in `lib/l10n/` via Flutter’s localization toolchain (`flutter gen-l10n` from IDE or pub). Commit regenerated files with the feature change. +- Keep environment secrets outside source control; configuration surfaces and self-hosted setup notes live in `docs/`. diff --git a/docs/flutter_vs_openwebui_comparison.md b/docs/flutter_vs_openwebui_comparison.md deleted file mode 100644 index 431ac43..0000000 --- a/docs/flutter_vs_openwebui_comparison.md +++ /dev/null @@ -1,190 +0,0 @@ -# Conduit (Flutter) vs Open-WebUI Web Client: Architecture Comparison, Issues, and Improvements - -## Executive Summary - -- Conduit aligns closely with Open-WebUI’s backend contract (auth, chat, tasks, sockets, files, i18n). -- Largest gaps: inconsistent background task flow vs SSE, partial parity for socket event mirroring, file/image handling differences, settings sync, and error UX. -- This document lists concrete issues with targeted improvements that match AGENTS.md guardrails (small, surgical edits, no new deps unless justified). - -## Scope and Criteria - -- Compared major areas: networking, auth/token, chat send/streaming, sockets, files, settings, i18n, and error handling. -- Cross-referenced key files in `lib/` and `openwebui-src/` to identify parity gaps and opportunities. - ---- - -## Networking & API Layer - -- Flutter: `lib/core/services/api_service.dart` uses `Dio` with `ApiAuthInterceptor` and `ApiErrorInterceptor`, plus debug wrappers. - - Base URL: `ServerConfig.url`. - - Validates statuses `<400`. Adds custom headers safely. -- Web: `openwebui-src/src/lib/apis/**` uses `fetch`, explicit `Authorization` header, and returns JSON/SSE readers. - -Issues -- ApiErrorInterceptor file is referenced but not present in the workspace snapshot (potentially moved/renamed). Risk of inconsistent error shaping. -- `lib/core/services/connectivity_service.dart` defines a simple `dioProvider` that is not wired to project’s configured `Dio`. Possible confusion or unused provider. - -Improvements -- Ensure a single `Dio` source of truth. If `dioProvider` is unused, remove it to avoid drift. -- Verify the actual error interceptor path exists and standardizes error payloads (ensure 401, validation errors, and transport errors surface with actionable messages). If missing, add an error transformer consistent with web client’s `handleOpenAIError` patterns. - ---- - -## Authentication & Tokens - -- Flutter: `AuthStateManager` persists token via `OptimizedStorageService` and `FlutterSecureStorage`. Adds `Authorization: Bearer` in `ApiAuthInterceptor` only for required or optional endpoints. -- Web: On login, sets `localStorage.token` and uses token in `fetch` headers; `socket` `user-join` is also emitted. - -Issues -- Flutter’s auth interceptor strictly blocks required endpoints without token (401 synthesis). Web sometimes tries endpoint and shows backend error. Flutter approach is OK, but ensure optional endpoints are fully listed to match backend behavior. - -Improvements -- Keep the strict check but review endpoint lists in `ApiAuthInterceptor` to match Open-WebUI’s optional/required matrix (e.g., config and public assets). -- Add a token-expiry check cadence similar to web layout’s interval if not already running, or rely on backend 401 → logout flow. - ---- - -## Chat Send, Streaming, Tasks, and Sockets - -- Web: Primarily streams via SSE (`chatCompletion`) and relays to socket channels; also supports background task flow with `task_id` and event mirroring (`chat-events`, `channel-events`). -- Flutter: `ApiService.sendMessage` supports SSE-like stream but currently forces background tools flow (`useBackgroundTasks = true`), attaches `session_id`/`id`, and polls chat until tool sections are done. Socket integration exists via `SocketService` and `streaming_helper.dart` to listen to lines or JSON payloads. - -Issues -- SSE vs Task Mode: Flutter hard-forces background flow, which disables direct SSE streaming and can add latency. Web uses SSE for pure completions and task mode when tools/search/image-gen are active. -- Dynamic Channel Handling: `streaming_helper.dart` has line handlers and `chatHandler`, but suppression flags and switching between SSE and socket content may not mirror all event types from web (`chat:message:delta`, `chat:message:files`, `chat:message:error`, `source/citation`, confirmation, etc.). -- Stop/Cancel: Web manages `taskIds` on active chat to stop. Flutter exposes `stopTask` but does not surface a complete UI flow in providers/widgets here. - -Improvements -- Restore dual-path streaming: - - Use pure SSE (no `session_id`/`id`) when no tools/web-search/image-gen are used to reduce latency and match web UX. - - Use background task + dynamic channel session only when features require it. -- Expand event handling parity in `streaming_helper.dart` to map Open-WebUI event types to mobile UI updates (files, citations, errors, followups). -- Wire cancel/stop control in UI: keep the task API and expose current `taskIds` per chat to stop ongoing responses. - ---- - -## Files and Attachments - -- Web: Uses `/api/v1/files/` with streaming status for processing; images can be inlined in content; shows progress. -- Flutter: `FileAttachmentService` converts images to data-URL instead of uploading; non-images upload via `ApiService.uploadFile` (multipart). `AttachmentUploadQueue` exists for background/offline retries. - -Issues -- Image Handling Divergence: Converting images to data URLs increases payload size and memory; web often uploads and references by id/URL, enabling server-side processing (RAG, OCR, etc.). -- Processing Status: Web listens to file processing SSE to surface parse status; Flutter does not reflect live processing feedback after upload. - -Improvements -- Prefer consistent behavior: upload images too (like web) and store file `id`, letting server handle compression/processing. -- Optionally implement file processing progress by consuming `/files/{id}/status` SSE (if available) and reflect it in `FileAttachmentWidget`. - ---- - -## Settings and Preferences - -- Web: `settings` store persists UI prefs, updates to backend via `updateUserSettings` under `/users/user/settings/update` with `{ ui: settings }`. -- Flutter: `SettingsService` persists locally via `SharedPreferences`; `userSettingsProvider` fetches server settings via `api.getUserSettings()` returning `UserSettings` model. - -Issues -- Potential divergence between local-only settings and backend user settings (`ui` namespace). Some settings (e.g., haptics, stream_response default, chat direction) exist on web but not mirrored in Flutter’s `UserSettings`. - -Improvements -- Align `UserSettings` fields with backend `ui` structure where applicable; when user is authenticated, prefer server-backed settings for cross-device consistency and fall back to local when offline. -- When settings change, POST updates to backend similar to web (`/users/user/settings/update`). Add a small merge strategy: local-only keys remain local, cross-device keys go to server. - ---- - -## Internationalization (i18n) - -- Web: `i18next` with lazy-loaded JSON; language auto-detect and backend default locale; sets `lang` attribute. -- Flutter: `gen-l10n` ARB files with `AppLocalizations`, docs in `docs/localization.md` and CI step. - -Issues -- Parity of strings: ensure Flutter ARB keys cover web parity for shared concepts (errors, chat UI hints, settings labels). Some strings appear hardcoded in Flutter widgets (e.g., "Attachments"). - -Improvements -- Move visible strings to ARB and reuse placeholders/ICU. Mirror important UI preferences and messages so translation workflows match. - ---- - -## Error Handling and UX - -- Web: Centralized toast errors (e.g., `handleOpenAIError` path, Error.svelte rendering message/detail with fallbacks). -- Flutter: `ApiErrorInterceptor` (referenced), `ErrorBoundary`, and some ad-hoc `debugPrint`s. - -Issues -- Missing or moved `ApiErrorInterceptor` risks inconsistent UX. Error messages from task flow/polling are not always promoted to UI components. - -Improvements -- Ensure API errors map to user-friendly messages, with context (network vs auth vs provider error). Surface task/polling errors in the chat UI just like streaming failures. - ---- - -## Connectivity and Offline - -- Flutter: `connectivity_service.dart` provides online/offline providers; `AttachmentUploadQueue` retries. -- Web: Browser online/offline events; no background file queue. - -Improvements -- Good mobile-first enhancement: keep AttachmentUploadQueue. Consider surfacing an inline banner or per-file retry affordances. - ---- - -## Sockets - -- Web: Socket.IO setup in `+layout.svelte`, emits `user-join`, registers `chat-events` and `channel-events`, forwards streamed lines to channel. -- Flutter: `SocketService` mirrors handshake headers, reconnect flow, and event subscription methods. - -Issues -- Ensure socket path `/ws/socket.io` and headers match server expectations across reverse proxies; feature flags in mobile to prefer WS-only if environment requires it. - -Improvements -- Expose transport mode in settings (already present, `socket_transport_mode`), and surface diagnostics screen to test connectivity. - ---- - -## Security & Privacy - -- Flutter: Secure storage for token, avoids logging secrets, custom headers filtered. Web: localStorage for token. - -Improvements -- Maintain secure storage for mobile; avoid verbose logging of payloads. Redact tokens in debug logs. - ---- - -## Concrete Action Items (Minimal, Targeted) - -1) Streaming mode parity -- In `ApiService.sendMessage`, choose SSE when no tools/web_search/image_generation; use background task session only when required. -- Keep `streaming_helper.dart` suppression flags but extend to support more event types from web. - -2) Files -- Upload images via `/api/v1/files/` instead of converting to data URLs. Store `id` and let server serve compressed/derived forms. -- Optionally consume processing status SSE for richer feedback. - -3) Settings sync -- Map `UserSettings` to backend `ui` fields; on change, POST to `/users/user/settings/update` similar to web. - -4) Error handling -- Ensure `ApiErrorInterceptor` exists and standardizes Dio exceptions. Add chat-level error surfacing in providers/widgets for background task flow. - -5) Cleanup and consistency -- Remove or wire the unused `dioProvider` from `connectivity_service.dart`. -- Move literal strings like "Attachments" into ARB files. - -6) Diagnostics -- Add a hidden debug screen to exercise socket connectivity and API endpoints (a wrapper exists in `api_service.debugApiEndpoints`). - ---- - -## Deferred / Optional (Non-breaking) - -- Stop/Cancel UX parity: expose active `taskIds` and provide a Stop button for ongoing responses. -- Model/tool server parity: ensure `tool_servers` payload and function-calling hints are preserved (already partially implemented). -- Performance: Consider `StreamTransformer` backpressure tuning in `streaming_helper.dart` for low-end devices. - ---- - -## Justification and Guardrails - -- Minimal changes; no new dependencies required. -- Aligns with Open-WebUI semantics for better feature parity and user expectations. -- Improves robustness and UX while preserving current architecture and patterns (Riverpod, Dio, interceptors, providers).