Commit Graph

167 Commits

Author SHA1 Message Date
Dayuan Jiang
4dbda5ba8e refactor: extract diagram tool handlers to dedicated hook
- Create useDiagramToolHandlers hook for display_diagram, edit_diagram, append_diagram
- Remove ~300 lines from chat-panel.tsx
- Remove unused stopRef
- Gate debug console.log statements with DEBUG constant
2025-12-24 10:15:41 +09:00
Dayuan Jiang
1fab261cd0 refactor: extract dev XML streaming simulator to separate component (#388)
- Move DEV_XML_PRESETS constants to new file
- Create DevXmlSimulator component with all simulator logic
- Add preset dropdown with 5 test cases including HTML escape test
- Set default interval to 1ms and chunk size to 10 chars
- Simplify chat-panel.tsx by removing ~130 lines of inline code
2025-12-24 09:52:50 +09:00
Dayuan Jiang
7a4a04c263 fix: remove unused partialXmlRef prop from ChatMessageDisplay (#387) 2025-12-24 09:37:32 +09:00
Dayuan Jiang
3218ccc909 feat: add dev XML streaming simulator for UI debugging (#385) 2025-12-24 09:29:29 +09:00
Dayuan Jiang
d3be96de79 refactor: redesign config panels with refined minimal aesthetic (#384)
- Add CSS design system tokens (surfaces, borders, animations) to globals.css
- Update dialog.tsx with rounded-2xl, shadow-dialog, refined close button
- Enhance input.tsx with rounded-xl and refined focus states
- Refactor settings-dialog with SettingItem pattern and consistent control sizing
- Refactor model-config-dialog with ConfigSection/ConfigCard helpers
- Replace emerald-* classes with success design tokens
- Remove unused ValidationButton component and scrollState
2025-12-23 21:52:04 +09:00
Dayuan Jiang
b2dfd5b890 fix: display correct quota values in limit toast (#383)
- Parse JSON error response from server to get actual used/limit values
- Previously showed 0/0 due to race condition (config fetch vs error)
- AI SDK puts full response body in error.message for non-OK responses
- Updated all quota toasts (request, token, TPM) to use server values
2025-12-23 21:08:21 +09:00
Dayuan Jiang
7de192e1fa fix: enable progressive diagram rendering during streaming (#380)
- Add extractCompleteMxCells() to extract only complete mxCell elements from partial XML
- Remove useEffect cleanup that was killing debounce timeouts on every re-render
- Wrap XML in <root> tags for proper DOMParser validation

Previously, diagrams only rendered after ALL XML finished streaming because:
1. useEffect cleanup cleared the 150ms debounce timeout on every message change
2. DOMParser rejected partial XML like '<mxCell id="2" value="...' (incomplete)

Now each complete mxCell renders progressively as it finishes streaming.
2025-12-23 18:54:03 +09:00
Dayuan Jiang
97ae9395cd feat: add server-side quota tracking with DynamoDB (#379)
- Add dynamo-quota-manager.ts for atomic quota checks using ConditionExpression
- Enforce daily request limit, daily token limit, and TPM limit
- Return 429 with quota details (type, used, limit) when exceeded
- Quota is opt-in: only enabled when DYNAMODB_QUOTA_TABLE env var is set
- Remove client-side quota enforcement (server is now source of truth)
- Simplify use-quota-manager.tsx to only display toasts
- Add @aws-sdk/client-dynamodb dependency
2025-12-23 18:36:27 +09:00
Dayuan Jiang
5ec05eb100 refactor: simplify Langfuse integration with AI SDK 6 (#375)
- Remove manual token attribute setting (AI SDK 6 telemetry auto-reports)
- Use totalTokens directly instead of inputTokens + outputTokens calculation
- Fix sessionId bug in log-save/log-feedback (prevents wrong trace attachment)
- Hash IP addresses for privacy instead of storing raw IPs
- Fix isLangfuseEnabled() to check both keys for consistency
2025-12-23 16:26:45 +09:00
Dayuan Jiang
9aec7eda79 fix: add continuation retry limit for truncated diagrams (#372)
Previously, continuation mode (for truncated XML) had unlimited client-side
retries, relying only on server stepCountIs(5) limit. This could cause
excessive API calls (495 observed) when XML truncation kept occurring.

Added MAX_CONTINUATION_RETRY_COUNT=2 to limit continuation attempts:
- After 2 failed continuation attempts, shows error toast and stops
- Resets on successful completion or user-initiated message
- Also resets when quota limits are hit
2025-12-23 14:17:06 +09:00
Dayuan Jiang
8cb7494d16 feat(i18n): add translations for model configuration UI (#368)
- Add ~40 new translation keys for model-config-dialog and model-selector
- Support English, Chinese, and Japanese translations
- Replace all hardcoded strings with dictionary lookups
2025-12-23 11:42:27 +09:00
Dayuan Jiang
b5734aa5e1 chore: hide notice icon from header (#366) 2025-12-23 10:08:14 +09:00
Dayuan Jiang
3521495ead chore: conditionally show about and notice based on env var (#358) 2025-12-23 00:32:22 +09:00
Biki Kalita
84959637db Support subdirectory deployment and fix API path handling (#311)
* feat: support subdirectory deployment (NEXT_PUBLIC_BASE_PATH)

* removed unwanted check and fix favicon issue

* Use getAssetUrl for manifest assets to avoid undefined NEXT_PUBLIC_BASE_PATH

* Add validation warning for NEXT_PUBLIC_BASE_PATH format

---------

Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
2025-12-22 23:28:55 +09:00
Twelveeee
6e2d98e52d move Language Selector into SettingDialog (#352)
* fix:custom model setting bug

* refactor: consolidate aiProvider checks for cleaner code

* fix:Integrated the language selection option into the `SettingsDialog`

* fix:useSearchParams() should be wrapped in a suspense boundary at page

* fix: improve semantic HTML and maintainability

- Replace nested button>a with proper anchor element for GitHub link
- Use i18n.locales.map() with LANGUAGE_LABELS for language options

---------

Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
2025-12-22 22:54:25 +09:00
Dayuan Jiang
85cb441e26 feat: multi-provider model configuration with UI/UX improvements (#355)
* feat: add multi-provider model configuration

- Add model config dialog for managing multiple AI providers
- Support for OpenAI, Anthropic, Google, Azure, Bedrock, OpenRouter, DeepSeek, SiliconFlow, Ollama, and AI Gateway
- Add model selector dropdown in chat panel header
- Add API key validation endpoint
- Add custom model ID input with keyboard navigation
- Fix hover highlight in Command component
- Add suggested models for each provider including latest Claude 4.5 series
- Store configuration locally in browser

* feat: improve model config UI and move selector to chat input

- Move model selector from header to chat input (left of send button)
- Add per-model validation status (queued, running, valid, invalid)
- Filter model selector to only show verified models
- Add editable model IDs in config dialog
- Add custom model input field alongside suggested models dropdown
- Fix hover states on provider buttons and select triggers
- Update OpenAI suggested models with GPT-5 series
- Add alert-dialog component for delete confirmation

* refactor: revert shadcn component changes, apply hover fix at usage site

* feat: add AWS credentials support for Bedrock provider

- Add AWS Access Key ID, Secret Access Key, Region fields for Bedrock
- Show different credential fields based on provider type
- Update validation API to handle Bedrock with AWS credentials
- Add region selector with common AWS regions

* fix: reset Test button after validation completes

* fix: reset validation button to Test after success

* fix: complete bedrock support and UI/UX improvements

- Add bedrock to ALLOWED_CLIENT_PROVIDERS for client credentials
- Pass AWS credentials through full chain (headers → API → provider)
- Replace non-existent GPT-5 models with real ones (o1, o3-mini)
- Add accessibility: aria-labels, focus-visible rings, inline errors
- Add more AWS regions (Ohio, London, Paris, Mumbai, Seoul, São Paulo)
- Fix setTimeout cleanup with useRef on component unmount
- Fix TypeScript type consistency in getSelectedAIConfig fallback

* chore: remove unused code

- Remove unused setAccessCodeRequired state in chat-panel.tsx
- Remove unused getSelectedModel export in model-config.ts

* fix: UI/UX improvements for model configuration dialog

- Add gradient header styling with icon badge
- Change Configuration section icon from Key to Settings2
- Add duplicate model detection with warning banner and inline removal
- Filter out already-added models from suggestions dropdown
- Add type-to-confirm for deleting providers with 3+ models
- Enhance delete confirmation dialog with warning icon
- Improve model selector discoverability (show model name + chevron)
- Add truncation for long model names with title tooltip
- Remove AI provider settings from Settings dialog (now in Model Config)
- Extract ValidationButton into reusable component

* fix: prevent duplicate model IDs within same provider

- Block adding model if ID already exists in provider
- Block editing model ID to match existing model in provider

* fix: improve duplicate model ID notifications

- Add toast notification when trying to add duplicate model
- Allow free typing when editing model ID, validate on blur
- Show warning toast instead of blocking input

* fix: improve duplicate model validation UX in config dialog

- Add inline error display for duplicate model IDs
- Show red border on input when error exists
- Validate on blur with shake animation for edit errors
- Prevent saving empty model names
- Clear errors when user starts typing
- Simplify error styling (small red text, no heavy chips)
2025-12-22 22:36:36 +09:00
Dayuan Jiang
68ea4958b8 feat: display app version in Settings dialog (#337) 2025-12-21 00:55:54 +09:00
Biki Kalita
378bef435e Add i18n support, language toggle UI, and translate Settings dialog (#334)
* i18n support added

* fix: align i18n implementation with Next.js 16 guide

- Rename middleware.ts to proxy.ts (Next.js 16 convention)
- Fix params type to Promise<{lang: string}> for layout/metadata
- Add 'server-only' directive and dynamic imports to dictionaries.ts
- Add hasLocale type guard and notFound() for invalid locales
- Wrap LanguageToggle in Suspense for useSearchParams
- Fix dictionary key mismatch (learnmore -> learnMore)
- Improve Chinese translations per Gemini review:
  - loading ellipsis, new -> 新建, styledMode -> 精致
  - goodResponse/badResponse -> 有帮助/无帮助
  - closeProtection -> 关闭确认, fileExceeds phrasing
- Improve Japanese translations per Gemini review:
  - closeProtection -> ページ離脱確認
  - invalidAccessCode phrasing, appendDiagram -> に追加
  - styledMode -> スタイル付き

---------

Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
2025-12-20 14:48:54 +00:00
Dayuan Jiang
f087b54ee4 feat: add get_shape_library tool for AI icon discovery (#335)
* feat: add get_shape_library tool for AI icon discovery

- Add server-side tool that returns shape library documentation
- AI can fetch icon/shape names on-demand before generating diagrams
- Includes path traversal protection and input sanitization
- Library index embedded in tool description for discoverability
- Supports 33 libraries: AWS, Azure, GCP, Kubernetes, Cisco, etc.

* fix: improve get_shape_library error handling and imports

- Move fs/path imports to top of file (avoid dynamic imports per call)
- Distinguish file-not-found vs other errors in catch block
- Include invalid input in validation error message
- Log unexpected errors for debugging

* docs: add get_shape_library to system prompt tool list

- Add Tool4 (get_shape_library) to available tools section
- Add usage guidance in 'Choose the right tool' section
- Update AWS icons note to reference get_shape_library for icon discovery

* fix: display get_shape_library tool output in chat UI

* fix: correct state check for get_shape_library output display

* fix: make get_shape_library output respect fold state

* style: auto-format with Biome

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-12-20 23:19:49 +09:00
E66Crisp
81eb71e704 fix(components): Send and sidebar buttons become inaccessible when chat-panel is resized (#309) 2025-12-18 21:16:32 +09:00
E66Crisp
58b6b19526 fix: Prevent DrawIO remount and data loss when resizing window across 768px breakpoint (#306)
* fix: Prevent DrawIO remount and data loss when resizing window across 768px breakpoint

* fix: prevent DrawIO remount and data loss when resizing window

- Move key from ResizablePanelGroup to chat-panel only
- Save diagram to localStorage before breakpoint change
- Restore defaultSize on drawio-panel to prevent layout flash
- Keep save button functionality from main

* fix: reset draw.io ready state on breakpoint change to restore diagram

* fix: skip initial render save and remove console logs

- Add isInitialRenderRef to skip unnecessary save/reset on first render
- Remove console.log statements for production cleanliness
- Add eslint-disable comment explaining loadDiagram dependency

---------

Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
2025-12-18 21:14:10 +09:00
Dayuan Jiang
f65ef548b2 fix: make draw.io built-in save button work with mouse tracking (#296)
- Add showSaveDialog state to DiagramContext for shared state
- Add mouse tracking to only respond to save events when mouse is over draw.io panel
- Prevents save dialog from opening when clicking Send in chat panel
- Add DialogDescription to SaveDialog for accessibility
2025-12-17 20:24:53 +09:00
Dayuan Jiang
741a00db89 Revert "fix: make draw.io built-in save button work (#293)" (#294)
This reverts commit bcc6684ecb.
2025-12-17 19:46:52 +09:00
Dayuan Jiang
bcc6684ecb fix: make draw.io built-in save button work (#293)
- Lift showSaveDialog state to DiagramContext for sharing between components
- Add onSave handler to DrawIoEmbed that opens the save dialog
- Add guard (isSavingRef) with 1s delay to prevent repeated save events from draw.io
- Add deprecation notice to custom download button tooltip

Closes #93, Closes #290
2025-12-17 19:14:15 +09:00
Dayuan Jiang
439bdd4577 feat: add MCP server package for npx distribution (#284)
* feat: add MCP server package for npx distribution

- Self-contained MCP server with embedded HTTP server
- Real-time browser preview via draw.io iframe
- Tools: start_session, display_diagram, edit_diagram, get_diagram, export_diagram
- Port retry limit (6002-6020) and session TTL cleanup (1 hour)
- Published as @next-ai-drawio/mcp-server on npm

* chore: bump version to 0.1.2

* docs: add MCP server section to README (preview feature)

* docs: add multi-client installation instructions for MCP server

* fix: exclude packages from Next.js build

* docs: use @latest instead of -y flag for npx (match Playwright MCP style)

* chore: bump version to 0.4.3 and add release notes

* chore: remove release notes

* feat: add MCP server notice to example panel
2025-12-17 14:50:07 +09:00
Dayuan Jiang
cd76fa615e fix: edit_diagram streaming and JSON repair improvements (#271)
- Add shared editDiagramOriginalXmlRef between streaming preview and tool handler
  to avoid conflicts when applying operations (fixes "cell already exists" errors)
- Add JSON repair preprocessing to fix LLM-generated malformed JSON like `:=`
- Filter out tool calls with invalid/undefined inputs from interrupted streaming
- Remove perf console logs
2025-12-15 21:28:31 +09:00
Dayuan Jiang
f175276872 refactor: replace text-based edit_diagram with ID-based operations (#267)
* refactor: replace text-based edit_diagram with ID-based operations

- Add applyDiagramOperations() function using DOMParser for ID lookup
- New schema: operations array with type (update/add/delete), cell_id, new_xml
- Update chat-panel.tsx handler for new operations format
- Update OperationsDisplay component to show operation type and cell_id
- Simplify system prompts with new ID-based examples
- Add ID validation for add operations
- Add warning for edges referencing deleted cells

* fix: add ID validation to update operation and remove dead code

- Add ID mismatch validation to update operation (consistency with add)
- Remove orphaned replaceXMLParts function (~300 lines of dead code)
- Update cell_id schema description for clarity
- Add unit tests for applyDiagramOperations (11 tests)
2025-12-15 14:22:56 +09:00
Dayuan Jiang
ac1c2ce044 fix: remove overly aggressive message filtering on restore (#263)
The hasValidDiagramXml filter was deleting valid messages that had minor
XML issues. Error handling in handleDisplayChart now catches all errors,
so filtering is no longer needed - invalid XML just won't load the diagram
but the conversation is preserved.
2025-12-14 21:49:08 +09:00
Dayuan Jiang
78a77e102d fix: prevent browser crash during long streaming sessions (#262)
- Debounce streaming diagram updates (150ms) to reduce handleDisplayChart calls by 93%
- Debounce localStorage writes (1s) to prevent blocking main thread
- Limit diagramHistory to 20 entries to prevent unbounded memory growth
- Clean up debounce timeout on component unmount to prevent memory leaks
- Add console timing markers for performance profiling

Fixes #78
2025-12-14 21:23:14 +09:00
Dayuan Jiang
55821301dd fix: recover from invalid XML in localStorage on startup (#261)
When LLM generates invalid XML, the app previously saved corrupted messages
to localStorage, causing an unrecoverable crash loop on restart.

This fix validates messages when restoring from localStorage and filters out
any with invalid diagram XML. Users see a toast notification when corrupted
messages are removed.

Fixes #240
2025-12-14 20:01:24 +09:00
Dayuan Jiang
f743219c03 feat: add minimal style mode toggle for faster diagram generation (#260)
* feat: add minimal style mode toggle for faster diagram generation

- Add Minimal/Styled toggle switch in chat input UI
- When enabled, removes color/style instructions from system prompt
- Faster generation with plain black/white diagrams
- Improves XML auto-fix: handle foreign tags, extra closing tags, trailing garbage
- Fix isMxCellXmlComplete to strip Anthropic function-calling wrappers
- Add debug logging for truncation detection diagnosis

* fix: prevent false XML parse errors during streaming

- Escape unescaped & characters in convertToLegalXml() before DOMParser validation
- Only log console.error for final output, not during streaming updates
- Prevents Next.js dev mode error overlay from showing for expected streaming states
2025-12-14 19:38:40 +09:00
Dayuan Jiang
0851b32b67 refactor: simplify LLM XML format to output bare mxCells only (#254)
* refactor: simplify LLM XML format to output bare mxCells only

- Update wrapWithMxFile() to always add root cells (id=0, id=1) automatically
- LLM now generates only mxCell elements starting from id=2 (no wrapper tags)
- Update system prompts and tool descriptions with new format instructions
- Update cached responses to remove root cells and wrapper tags
- Update truncation detection to check for complete mxCell endings
- Update documentation in xml_guide.md

* fix: address PR review issues for XML format refactor

- Fix critical bug: inconsistent truncation check using old </root> pattern
- Fix stale error message referencing </root> tag
- Add isMxCellXmlComplete() helper for consistent truncation detection
- Improve regex patterns to handle any attribute order in root cells
- Update wrapWithMxFile JSDoc to document root cell removal behavior

* fix: handle non-self-closing root cells in wrapWithMxFile regex
2025-12-14 14:04:44 +09:00
Dayuan Jiang
2e24071539 fix: shorten toast notification duration to 2 seconds (#253) 2025-12-14 13:04:18 +09:00
Dayuan Jiang
66bd0e5493 feat: add append_diagram tool and improve truncation handling (#252)
* feat: add append_diagram tool for truncation continuation

When LLM output hits maxOutputTokens mid-generation, instead of
failing with an error loop, the system now:

1. Detects truncation (missing </root> in XML)
2. Stores partial XML and tells LLM to use new append_diagram tool
3. LLM continues generating from where it stopped
4. Fragments are accumulated until XML is complete
5. Server limits to 5 steps via stepCountIs(5)

Key changes:
- Add append_diagram tool definition in route.ts
- Add append_diagram handler in chat-panel.tsx
- Track continuation mode separately from error mode
- Continuation mode has unlimited retries (not counted against limit)
- Error mode still limited to MAX_AUTO_RETRY_COUNT (1)
- Update system prompts to document append_diagram tool

* fix: show friendly message and yellow badge for truncated output

- Add yellow 'Truncated' badge in UI instead of red 'Error' when XML is incomplete
- Show friendly error message for toolUse.input is invalid errors
- Built on top of append_diagram continuation feature

* refactor: remove debug logs and simplify truncation state

- Remove all debug console.log statements
- Remove isContinuationModeRef, derive from partialXmlRef.current.length > 0

* docs: fix append_diagram instructions for consistency

- Change 'Do NOT include' to 'Do NOT start with' (clearer intent)
- Add <mxCell id="0"> to prohibited start patterns
- Change 'closing tags </root></mxGraphModel>' to just '</root>' (wrapWithMxFile handles the rest)
2025-12-14 12:34:34 +09:00
Dayuan Jiang
987dc9f026 fix: add configurable MAX_OUTPUT_TOKENS to prevent truncation (#251)
- Add MAX_OUTPUT_TOKENS env var (fixes output truncation with Bedrock)
- Remove redundant fixToolCallInputs function
- Remove jsonrepair dependency
- Consolidate duplicate lastMessage/userInputText variables
2025-12-13 23:28:41 +09:00
dayuan.jiang
4b838fd6d5 feat: add XML auto-fix and improve validator accuracy
- Add autoFixXml() to automatically repair common XML issues:
  - CDATA wrapper removal
  - Duplicate attribute removal
  - Unescaped & and < character escaping
  - Invalid entity reference fixing
  - Unclosed tag completion
  - Nested mxCell flattening
  - Duplicate ID renaming

- Improve validateMxCellStructure() with DOM + regex approach:
  - Use DOMParser for syntax error detection (94% recall)
  - Add regex checks for edge cases
  - Stateful parser for handling > in attribute values

- Integrate validateAndFixXml() in chat-message-display and diagram-context
  - Auto-repair invalid XML before loading
  - Log fixes applied for debugging

Metrics: 99.77% accuracy, 94.06% recall, 94.4% auto-fix success rate
2025-12-13 16:11:47 +09:00
Dayuan Jiang
aa15519fba fix: handle malformed XML from DeepSeek gracefully (#235)
* fix: handle malformed XML from DeepSeek gracefully

Add early XML validation with parsererror check before calling
replaceNodes to prevent application crashes when AI models
generate malformed XML with unescaped special characters.

Changes:
- Add toast import from sonner
- Parse and validate XML before processing
- Add parsererror detection to catch malformed XML early
- Wrap replaceNodes in try-catch for additional safety
- Add user-friendly toast notifications for all error cases
- Change console.log to console.error for validation failures

Fixes #220 #230 #231

* fix: prevent toast spam during streaming and merge silent failure fixes

- Only show error toasts after streaming completes (not during partial updates)
- Track which tool calls have shown errors to prevent duplicate toasts
- Merge clipboard copy error handling from PR #236
- Merge feedback submission error handling from PR #237
- Add comments explaining streaming vs completion behavior

* refactor: simplify toast deduplication with boolean flag

Based on code review feedback, simplified the approach from tracking
per-tool-call IDs in a Set to using a single boolean flag.

Changes:
- Replaced Set<string> with boolean ref for toast tracking
- Removed toolCallId and showToast parameters from handleDisplayChart
- Reset flag when streaming starts (simpler mental model)
- Same behavior: one toast per streaming session, no spam

Benefits:
- Fewer concepts (1 boolean vs Set + 2 parameters)
- No manual coordination between call sites
- Easier to understand and maintain
- ~15 fewer lines of tracking logic

* fix: only show toast for final malformed XML, not during streaming

- Remove errorToastShownRef tracking (no longer needed)
- Add showToast parameter to handleDisplayChart (default false)
- Pass false during streaming (XML may be incomplete)
- Pass true at completion (show toast if final XML is malformed)
- Simpler and more explicit error handling
2025-12-12 14:52:25 +09:00
Dayuan Jiang
c2c65973f9 fix: revert UI and notify user when feedback submission fails (#237)
When feedback submission to the API fails, revert the optimistic
UI update and show a toast notification to inform the user.

Changes:
- Add toast import from sonner
- Change console.warn to console.error for proper logging
- Add toast.error() notification when API call fails
- Revert optimistic UI update by removing feedback from state

Previously, feedback submission failures were completely silent.
Users would see the thumbs-up/down visual feedback but their
feedback was never recorded. This creates a false sense that
the feedback was successfully submitted.

Now users are immediately notified when submission fails and
can retry their feedback.
2025-12-12 14:08:20 +09:00
Dayuan Jiang
b5db980f69 fix: add user feedback for clipboard copy failures (#236)
Add toast notification when clipboard copy operation fails,
so users know when their copy attempt was unsuccessful.

Changes:
- Add toast import from sonner
- Add toast.error() notification when clipboard copy fails
- Show clear message: "Failed to copy message. Please copy
  manually or check clipboard permissions."

Previously, clipboard copy failures were only indicated by a
brief visual state change (setCopyFailedMessageId), which users
might miss. Now users receive persistent feedback when copy
operations fail.
2025-12-12 14:06:53 +09:00
Shashi kiran M S
c9b60bfdb2 feat: Add a new chat button with a confirmation modal (#229)
* feat: Add a new chat button with a confirmation modal

* Fix for PR comments

* fix: add error handling and proper cleanup in handleNewChat

- Add try-catch for localStorage operations to handle quota exceeded,
  private browsing, and other storage errors
- Use handleFileChange([]) instead of setFiles([]) to properly clear
  pdfData Map alongside files
- Only show success toast when localStorage operations succeed
- Show warning toast if localStorage fails but chat state is cleared

---------

Co-authored-by: Dayuan Jiang <jdy.toh@gmail.com>
2025-12-12 10:08:18 +09:00
Twelveeee
f170bb41ae fix:custom model setting bug (#227)
* fix:custom model setting bug

* refactor: consolidate aiProvider checks for cleaner code

---------

Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
2025-12-12 09:33:07 +09:00
try2love
8fd3830b9d Fix/clipboard (#189)
* bugfix: clipboard error bug

* fix: use try-catch fallback for clipboard API instead of feature detection

---------

Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
2025-12-11 21:09:42 +09:00
Biki Kalita
77a25d2543 Persist processed tool calls to prevent replay after chat restore (#224) 2025-12-11 20:48:48 +09:00
Dayuan Jiang
b9da24dd6d fix: limit auto-retry to 3 attempts and enforce quota checks (#219)
- Add MAX_AUTO_RETRY_COUNT (3) to prevent infinite retry loops
- Check token and TPM limits before each auto-retry
- Reset retry counter on user-initiated messages
- Show toast notification when limits are reached

Fixes issue where models returning invalid tool inputs caused 45+ API
requests due to sendAutomaticallyWhen having no retry limit or quota check.
2025-12-11 17:56:40 +09:00
Dayuan Jiang
869391a029 refactor: eliminate code duplication (DRY principle) (#211)
## Problem Solved
Previous refactoring added 105 lines (1476→1581) by extracting code into separate files without eliminating duplication. This refactor focuses on reducing code size through deduplication while maintaining file separation for maintainability.

## Summary
- Reduced total lines from 1581 to 1519 (-62 lines, 3.9% reduction)
- Eliminated duplicate patterns using generic helpers and factory functions
- Maintained file structure for maintainability
- Zero functional changes - same behavior

### Phase 1: DRY use-quota-manager.tsx
- Created parseStorageCount() helper (eliminates 6x localStorage read duplication)
- Created createQuotaChecker() factory (consolidates 3 check function bodies)
- Created createQuotaIncrementer() factory (consolidates 3 increment function bodies)
- Result: 242→247 lines (+5 lines, but fully DRY with eliminated duplication)

### Phase 2: DRY chat-panel.tsx (1176→1109 lines, -67 lines)

#### 2.1: Extract checkAllQuotaLimits helper
- Replaced 3 occurrences of 18-line quota check blocks
- Saved 36 lines

#### 2.2: Extract sendChatMessage helper
- Replaced 3 occurrences of 21-line sendMessage+headers blocks
- Saved 42 lines

#### 2.3: Extract processFilesAndAppendContent helper
- Replaced 2 occurrences of file processing loops
- Handles PDF, text, and image files uniformly
- Async helper with optional image parts parameter
2025-12-11 14:28:02 +09:00
Dayuan Jiang
c0347dd55d fix: prevent diagram regeneration loop after successful display (#206)
- Changed sendAutomaticallyWhen to only auto-resubmit on tool errors
- Extracted logic to shouldAutoResubmit() function with JSDoc
- Added TypeScript interfaces for type safety (MessagePart, ChatMessage)
- Wrapped debug logs with DEBUG flag for production readiness
- Added TOOL_ERROR_STATE constant to avoid hardcoded strings

Problem: AI was regenerating diagrams 3+ times even after successful display
Root cause: lastAssistantMessageIsCompleteWithToolCalls auto-resubmits on both success AND error
Solution: Custom logic that only auto-resubmits on errors, stops on success
2025-12-11 09:47:30 +09:00
Biki Kalita
a047a6ff97 feat: Display AI reasoning/thinking blocks in chat interface (#152)
* feat: Add reasoning/thinking blocks display in chat interface

* feat: add multi-provider options support and replace custom reasoning UI with AI Elements

* resolve conflicting reasoning configs and correct provider-specific reasoning parameters

* try to solve conflict

* fix: simplify reasoning display and remove unnecessary dependencies

- Remove Streamdown dependency (~5MB) - reasoning is plain text only
- Fix Bedrock providerOptions merging for Claude reasoning configs
- Remove unsupported DeepSeek reasoning configuration
- Clean up unused environment variables (REASONING_BUDGET_TOKENS, REASONING_EFFORT, DEEPSEEK_REASONING_*)
- Remove dead commented code from route.ts

Reasoning blocks contain plain thinking text and don't need markdown/diagram/code rendering.

* feat: comprehensive reasoning support improvements

Major improvements:
- Auto-enable reasoning display for all supported models
- Fix provider-specific reasoning configurations
- Remove unnecessary Streamdown dependency (~5MB)
- Clean up debug logging

Provider changes:
- OpenAI: Auto-enable reasoningSummary for o1/o3/gpt-5 models
- Google: Auto-enable includeThoughts for Gemini 2.5/3 models
- Bedrock: Restrict reasoningConfig to only Claude/Nova (fixes MiniMax error)
- Ollama: Add thinking support for qwen3-like models

Other improvements:
- Remove ENABLE_REASONING toggle (always enabled)
- Fix Bedrock providerOptions merging for Claude
- Simplify reasoning component (plain text rendering)
- Clean up unused environment variables

* fix: critical bugs and documentation gaps in reasoning support

Critical fixes:
- Fix Bedrock shallow merge bug (deep merge preserves anthropicBeta + reasoningConfig)
- Add parseInt validation with parseIntSafe helper (prevents NaN errors)
- Validate all numeric env vars with min/max ranges

Documentation improvements:
- Add BEDROCK_REASONING_BUDGET_TOKENS and BEDROCK_REASONING_EFFORT to env.example
- Add OLLAMA_ENABLE_THINKING to env.example
- Update JSDoc with accurate env var list and ranges

Code cleanup:
- Remove debug console.log statements from route.ts
- Refactor duplicate providerOptions assignments

---------

Co-authored-by: Dayuan Jiang <34411969+DayuanJiang@users.noreply.github.com>
Co-authored-by: Dayuan Jiang <jdy.toh@gmail.com>
2025-12-11 00:24:43 +09:00
Dayuan Jiang
d2ba133eaf feat: add PDF and text file upload support (#205)
- Add client-side PDF text extraction using unpdf library
- Support text files (.txt, .md, .json, .csv, .py, .js, .ts, etc.)
- Add file preview with character count for PDF/text files
- Add 150k character limit for extracted content
- Highlight Paper to Diagram example with NEW badge
- Fix React hydration error by adding explicit IDs to ResizablePanelGroup
- Remove code duplication by centralizing file utilities in pdf-utils.ts
2025-12-10 21:32:35 +09:00
Dayuan Jiang
43e5993f47 fix: improve LLM diagram context awareness and image preview (#202)
- Add replaceHistoricalToolInputs to replace XML in tool calls with placeholders
- Send both previousXml and current xml so LLM can understand user's manual edits
- Update system message to mark current XML as authoritative source of truth
- Fix React StrictMode issue with blob URL cleanup in FilePreviewList
- Add unoptimized prop to Image components for blob URLs
2025-12-10 18:04:37 +09:00
try2love
5da4ef67ec feat:light/dark mode switch (#138)
Summary

- Adds browser theme detection on first visit using
prefers-color-scheme media query
- Renames localStorage key from dark-mode to
next-ai-draw-io-dark-mode for consistency with other keys
- Uses STORAGE_DIAGRAM_XML_KEY constant instead of hardcoded
string in diagram-context.tsx

Changes

app/page.tsx:
- On first visit (no saved preference), detect browser's color
scheme preference
- Update localStorage key to follow project naming convention
(next-ai-draw-io-*)

contexts/diagram-context.tsx:
- Import STORAGE_DIAGRAM_XML_KEY from chat-panel.tsx
- Replace hardcoded "next-ai-draw-io-diagram-xml" with the
constant
2025-12-10 09:21:15 +09:00