Commit Graph

142 Commits

Author SHA1 Message Date
Acbox 7de55f6b49 fix(web): prevent duplicate assistant message after refresh with tool-call sequences
When messages like [assistant(tool_calls), tool, assistant(text)] are
merged into a single ChatMessage by convertMessagesToChats, the merged
message uses the first assistant's ID. The SSE /messages/events backlog
(which uses >= for the since filter) could re-deliver the final assistant
message, and hasMessageWithId failed to recognize it because the merged
ID was different. This caused the last assistant message to appear twice
after a page refresh.

Track all original server message IDs in a Set (knownServerMessageIds)
so that hasMessageWithId can catch messages whose IDs were absorbed
during merging.
2026-03-31 18:46:48 +08:00
Acbox c77ba63074 fix(web): resolve Monaco editor theme conflicts with markstream-vue
Use stream-monaco's useMonaco composable instead of raw monaco-editor
to share the same theme registration system with markstream-vue.
Pass isDark prop to MarkdownRender to follow app dark mode.
2026-03-31 17:20:42 +08:00
Acbox 2d55c385a4 release: v0.6.1 2026-03-31 15:19:53 +08:00
Acbox f1dd30a388 fix: strip agent tags from IM/WebUI output and fix attachment display after refresh
Three independent bugs fixed:

1. IM channels were sending raw <attachments>/<reactions>/<speech> tag blocks
   alongside file attachments. Now ExtractAssistantOutputs strips these tags
   before building the outbound channel message.

2. WebUI rendered these tags as markdown after page refresh. Now
   extractMessageText strips agent tags for non-user messages.

3. WebUI lost attachment blocks after refresh because convertMessagesToChats
   did not call buildAssetBlocks when merging assistant messages into a
   pending tool-call group. Also made LinkOutboundAssets session-aware so
   assets are linked to the correct assistant message.
2026-03-31 15:11:57 +08:00
Ran 49613a283b release: v0.6.0 2026-03-30 15:23:26 +08:00
Ran fed7b68bd3 chore(web): adjust profile icon 2026-03-30 15:19:12 +08:00
Acbox bff9055d28 release: v0.6.0-beta.5 2026-03-29 20:16:17 +08:00
Yiming Qi ba0569c1fa feat(email): use popup flow for gmail oauth callback (#307)
* feat(email): use popup flow for gmail oauth callback

* fix(email): satisfy lint in oauth callback helper
2026-03-29 20:13:45 +08:00
Acbox 180a9287dd fix(web): read tool result from correct field in history loading
The SDK persists tool results as ToolResultPart with a "result" JSON field,
but extractAllToolResults was only reading "output", causing exec tool
stdout/stderr/exit_code to be lost when loading chat history.
2026-03-29 19:58:52 +08:00
Acbox 0b7ecd87f6 feat(web): use session-type icons for sidebar filter button
Replace the static Globe icon with dynamic type-specific icons
(MessageSquare, HeartPulse, Clock, GitBranch) that match the
session item icons, updating both icon and color on filter change.
2026-03-29 19:57:40 +08:00
Acbox 33f39c20ff feat: add per-message model and reasoning effort override
Allow users to select a different model and reasoning effort level
directly from the chat input toolbar, overriding the bot defaults
on a per-message basis. The backend accepts optional model_id and
reasoning_effort parameters via both WebSocket and HTTP APIs, with
request-level values taking priority over bot/session settings.

- Backend: extend wsClientMessage and LocalChannelMessageRequest with
  model_id/reasoning_effort fields; add ReasoningEffort to ChatRequest;
  update resolver to prioritize request-level reasoning effort
- Frontend: add ModelOptions and ReasoningEffortSelect shared components;
  refactor model-select to reuse ModelOptions; add model/reasoning
  selectors to chat input toolbar; initialize from bot settings
- Regenerate swagger spec and TypeScript SDK
2026-03-29 19:45:55 +08:00
Acbox 7825b49ff3 feat(web): add resizable session sidebar and inline file manager panel
Replace fixed-width session sidebar with a draggable resize handle on
its right edge (180–480px, persisted to localStorage). Convert the file
manager from a Sheet overlay to an embedded right-side panel with a
left-edge resize handle (320–800px, also persisted).
2026-03-29 19:23:10 +08:00
Acbox 0e646625bf feat: add compaction ratio setting to control partial context compaction
Allow users to configure what percentage of older messages to compact,
keeping the most recent portion intact. Default ratio is 80%, meaning
the oldest 80% of uncompacted messages are summarized while the newest
20% remain as-is for full-fidelity context.
2026-03-29 19:14:43 +08:00
Acbox bcda6f6fe6 refactor: replace Load More with Pagination across frontend and backend
- Replace all "Load More" / "Show More" buttons with Pagination components
  in model-list, bot-compaction, and bot-heartbeat views
- Convert backend log APIs (compaction, heartbeat, schedule) from
  cursor-based (before+limit) to offset+limit pagination with total_count
- Update SQL queries to use OFFSET+LIMIT and add COUNT queries
- Add shared parseOffsetLimit helper in handler_helpers.go
- Regenerate sqlc, Swagger docs, and TypeScript SDK
- Clean up unused i18n keys (loadMore, showMore, history.loadMore)
2026-03-29 18:49:30 +08:00
Acbox 716123d08d feat(web): redesign model card with colored capability icons and context window badges
Extract ModelCapabilities and ContextWindowBadge into shared components.
Model type badge moved to title row with icon, capabilities shown as
icon-only colored tags, context window formatted as colored badge (k/M).
Also add capability and context info to model select dropdown options.
2026-03-29 18:34:04 +08:00
Acbox c986c209ed fix(web): remove input group shadow and focus ring from chat input 2026-03-29 18:18:06 +08:00
Acbox 122382d7d4 fix(web): improve chat input UX — IME composing, send button, file upload
- Prevent Enter from sending message during IME composing (keyCode 229)
- Remove separator line between textarea and toolbar
- Change send/stop buttons to compact circular icon-only style
- Fix send icon color to white for dark mode visibility
- Add missing hidden file input element so the attach button works
2026-03-29 18:09:28 +08:00
Acbox bb56ed3048 fix(web): add missing size class to Search icon in model list 2026-03-29 17:53:06 +08:00
Acbox a2941967df refactor(web): migrate all icons from FontAwesome to Lucide and remove dead code
Replace all FontAwesome icon usage across 80+ Vue files with lucide-vue-next
components. Remove FontAwesome dependencies (@fortawesome/*) and global
registration from main.ts. Delete unused components (data-table, warning-banner,
session-metadata, bot-sidebar/bot-item in home, message-list, tts-provider-select),
dead utilities (channel-icons.ts, custom-icons.ts), and stale assets (vue.svg).
Update AGENTS.md to reflect the new icon strategy.
2026-03-29 17:46:33 +08:00
Acbox d133a85fe3 fix(web): attach JWT token to file download URL to fix auth error
Browser <a> tag downloads don't send Authorization headers, causing
"missing or malformed jwt" errors. Pass token via query param which
the backend JWT middleware already supports.
2026-03-29 17:43:42 +08:00
Acbox 6c2da4b2f5 feat(web,server): expose server version and commit hash in Profile page
Add version and commit_hash fields to the /ping endpoint response,
sourced from the existing internal/version package (ldflags or
Go build info). The frontend capabilities store reads these values
and displays them as badges at the bottom of the Profile page.
2026-03-29 17:38:33 +08:00
Acbox 13d2f668f5 fix(web): simplify Daily Tokens chart to show only Total Input/Output
Remove per-session-type (chat/heartbeat/schedule) bar series from the
Daily Tokens chart, keeping only aggregated Total Input and Total Output
as stacked bars for a cleaner visualization.
2026-03-29 17:22:10 +08:00
Acbox aad8724642 release: v0.6.0-beta.4 2026-03-29 16:30:15 +08:00
AlexMa233 f554eee20b fix(web): align browser context actions with settings pages (#302) 2026-03-29 16:29:12 +08:00
特菈 Dustella c44f25d90d fix(sidebar): fix desktop sidebar collapsed by default on first visit (#305)
- Fix cookie check logic: use `!includes('sidebar_state=false')` instead
  of `includes('sidebar_state=true')` so sidebar defaults to open when
  no cookie is set
- Add --sidebar-width CSS variable binding to desktop sidebar element
- Adjust SIDEBAR_WIDTH_MOBILE value

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 16:28:11 +08:00
Acbox 7626816b73 release: v0.6.0-beta.3 2026-03-29 04:03:34 +08:00
Acbox 057ebd0a1a release: v0.6.0-beta.2 2026-03-29 02:46:08 +08:00
Acbox 3c26109d79 fix(web): make streaming state per-session instead of global
Replace the global streaming ref with a streamingSessionId that
records which session is actively streaming. The streaming computed
now returns true only when the current session matches, so switching
sessions no longer leaks the generating indicator to unrelated sessions.
2026-03-29 01:04:34 +08:00
Acbox d9ffd8fb50 fix(web): ensure minimum horizontal padding for chat messages
Increase inner content padding from px-1/sm:px-2 to px-10 so messages
maintain comfortable horizontal margins on narrow viewports.
2026-03-29 01:04:27 +08:00
Acbox f09ab119a4 fix(web): pin chat input and make session list scrollable independently
Constrain the main layout to viewport height (h-dvh) and override
SidebarProvider's min-h-svh so the height chain propagates correctly.
Change main-container overflow from auto to hidden so the outer
container never scrolls. Use absolute-positioning pattern for
session sidebar ScrollArea (matching chat messages pattern) to
ensure sessions scroll independently while the chat input stays fixed.
2026-03-29 01:04:17 +08:00
Acbox c5f1477539 release: v0.6.0-beta.1 2026-03-29 00:09:05 +08:00
Acbox fd078d263b chore(i18n): add sidebar.settings 2026-03-29 00:05:07 +08:00
Acbox 6818361b7f chore(web): rename settings to profile 2026-03-29 00:03:49 +08:00
Acbox 0730ff2945 refactor: remove max_context_load_time and max_context_tokens from bot settings
These two fields controlled history context window (time-based) and token-based
trimming. They are no longer needed — the resolver now always uses the hardcoded
24-hour default and skips token-based history trimming.
2026-03-29 00:00:10 +08:00
Acbox 90ac222bc9 feat: auto-create search/tts providers at startup with enable toggle
- Add `enable` column (default false) to search_providers and tts_providers tables
- Auto-create default entries for all provider types on startup (disabled by default)
- Add enable/disable Switch toggle in frontend for both search and TTS providers
- Show green status dot in sidebar for enabled providers, sort enabled first
- Filter bot settings dropdowns to only show enabled providers
2026-03-28 23:47:09 +08:00
Acbox c0057b5c54 refactor(web): align route paths, page dirs and i18n keys with sidebar labels
- Rename route paths to match sidebar tab labels:
  models→providers, search-providers→web-search,
  memory-providers→memory, tts-providers→speech,
  email-providers→email, browser-contexts→browser,
  settings(profile)→profile
- Rename page directories accordingly
- Rename i18n keys: sidebar.models→providers, searchProvider→webSearch,
  memoryProvider→memory, ttsProvider→speech, emailProvider→email,
  browserContext→browser
- Fix bot detail tab value 'settings' → 'general' to match label
- Fix ZH bots.tabs.general untranslated ("General" → "通用")
- Align usage page title with sidebar label
2026-03-28 23:34:53 +08:00
Acbox eb99f75c37 feat(web): add bot context menu with details link and pin/unpin
Add a dropdown menu to each bot item in the chat sidebar with:
- "Details" option to navigate to the bot's settings page
- "Pin/Unpin" option to pin bots to the top of the list, persisted via localStorage
2026-03-28 19:44:36 +08:00
Acbox Liu bca13a13fa feat(web): introduce a brand new web ui (#281)
* feat(web): introduce a brand new web ui

* refactor(ui): align chat sidebar and UI components with Figma design

- Restyle chat page sidebar: header with icon/title, search input,
  section labels, and "new session" footer button
- Simplify bot-sidebar and session-sidebar to card-based layout
  matching Figma session card design (58px height, 26px avatar, status dots)
- Update master-detail-sidebar-layout with bg-sidebar and 53px header
- Unify border-radius across UI components to rounded-lg (8px):
  Card, Toggle, Alert, Popover, Item; Dialog uses rounded-xl (12px)

* refactor(ui): move shared theme and design tokens from web to ui package

CSS variables, @theme inline mappings, @custom-variant, and base layer
styles now live in @memohai/ui/style.css. The web app imports them via
@import "@memohai/ui/style.css", keeping only the Tailwind entry point
and web-specific imports (markstream-vue, @source).

* refactor(ui): apply flat design system from Figma spec

Overhaul @memohai/ui component styles to match the new "high-contrast,
flat" design language defined in the Figma design spec (DESIGN.md).

Theme:
- --primary-foreground: pure white -> #fafafa
- --ring: purple -> foreground color (focus rings no longer use brand purple)

Atoms (zero shadow, monochrome):
- Button: default bg-primary -> bg-foreground; add explicit "primary" variant for Send CTA
- Badge: rounded-full -> rounded-sm; default bg-primary -> bg-foreground; add warning/outline/size variants
- Alert: rounded-lg -> rounded-[10px]; remove shadow-sm; destructive drops bg-red-50
- Card: add shadow-lg, rounded-lg -> rounded-xl, py-6 -> p-6
- Input/Textarea: remove shadow, text-sm -> text-[16px], focus ring non-purple
- Checkbox: checked bg-primary -> bg-foreground
- Switch: checked bg-primary -> bg-foreground
- RadioGroup: indicator fill-primary -> fill-foreground
- Slider: range/thumb border-primary -> border-foreground

Floating panels (shadow-md):
- DropdownMenu/Combobox/Select/ContextMenu Content: shadow-lg -> shadow-md
- Sheet: shadow-2xl -> shadow-lg
- MenuItem destructive focus: bg-red-50 -> bg-accent

Other:
- Pagination active: bg-foreground text-background (black, not purple)
- Item variants: bg-transparent -> bg-background/bg-accent
- Tabs active: shadow-sm -> border-border
- Toggle: remove shadow-xs, unify hover to accent
- SelectTrigger/NativeSelect: remove shadow, unify focus ring

Docs:
- Add packages/ui/DESIGN.md with full design system spec
- Simplify apps/web/AGENTS.md, remove duplicated design info, reference DESIGN.md

* refactor(chat-ui): restructure chat page components and styles (#288)

* refactor(chat-ui): restructure chat page components and styles

* feat(chat): add collapsible sidebar for both sides

* feat(ui): add PinInput and BadgeCount components, align styles with Figma spec

New components:
- PinInput (OTP input): PinInput, PinInputGroup, PinInputSlot, PinInputSeparator
  based on reka-ui PinInput primitives with flat border-stitching design
- BadgeCount: circular numeric counter with default/destructive/secondary variants

Style updates to match Figma design:
- Sonner: border-radius from 1rem to var(--radius-lg) (10px)
- Table: add border border-border rounded-sm to container
- TagsInput: remove shadow-xs, rounded-md -> rounded-lg, ring-[3px] -> ring-2

Updated DESIGN.md with all new component specifications.

* chore: move up css to ui package

* refactor: change npm package from @memoh to @memohai

* Feat/chat layout (#295)

* refactor(chat-ui): restructure chat page components and styles

* feat(chat): add collapsible sidebar for both sides

* fix: update chat page icon

* style: refine UI components appearance

* style: refine UI components appearance

* chore(ci): update lock file

* refactor: new layout

* chore: adjust style

* fix: tauri ui size

* chore: remove bot session metadata

* refactor: text size and muted color

* fix: indirect height of bot-details pages

* feat: add 5 icons

* refactor: polish chat flow and settings navigation labels

Persist chat selection across pages, simplify provider/settings sidebars, and refine chat/session UX so navigation and composer behavior feel consistent without extra session/provider jumps.

* docs(web): refresh AGENTS frontend architecture guide

Expand and align the web AGENTS documentation with the current route structure, component inventory, chat transport flow, and store responsibilities so implementation guidance matches the codebase.

---------

Co-authored-by: Quincy <69751197+dqygit@users.noreply.github.com>
2026-03-28 19:15:39 +08:00
BBQ 7f9d6e4aba feat(acl): redesign ACL with conversation scope selector (#297)
Backend
- New subject kinds: all / channel_identity / channel_type
- Source scope fields on bot_acl_rules: source_channel,
  source_conversation_type, source_conversation_id, source_thread_id
- Fix source_scope_check constraint: resolve source_channel server-side
  (channel_type → subject_channel_type; channel_identity → DB lookup)
- Add GET /bots/:id/acl/channel-types/:type/conversations to list
  observed conversations by platform type
- ListObservedConversations: include private/DM chats, normalise
  conversation_type; COALESCE(name, handle) for display name
- enrichConversationAvatar: persist entry.Name → conversation_name
  (keeps Telegram group titles current on every message)
- Unify Priority type to int32 across Go types to match DB INTEGER;
  remove all int/int32 casts in service layer
- Fix duplicate nil guard in Evaluate; drop dead SourceScope.Channel field
- Migration 0048_acl_redesign

Frontend
- Drag-and-drop rule priority reordering (SortableJS/useSortable);
  fix reorder: compute new order from oldIndex/newIndex directly,
  not from the array (which useSortable syncs after onEnd)
- Conversation scope selector: searchable popover backed by observed
  conversations (by identity or platform type); collapsible manual-ID fallback
- Display: name as primary label, stable channel·type·id always shown
  as subtitle for verification
- bot-terminal: accessibility fix on close-tab button (keyboard events)
- i18n: drag-to-reorder, conversation source, manual IDs (en/zh)

Tests: update fakeChatACL to Evaluate interface; fix SourceScope literals.
SDK/spec regenerated.
2026-03-28 01:06:13 +08:00
Yiming Qi 64378d29ed feat: openai codex support (#292)
* feat(web): add provider oauth management ui

* feat: add OAuth callback support on port 1455

* feat: enhance reasoning effort options and support for OpenAI Codex OAuth

* feat: update twilight-ai dependency to v0.3.4

* refactor: promote openai-codex to first-class client_type, remove auth_type

Replace the previous openai-responses + metadata auth_type=openai-codex-oauth
combo with a dedicated openai-codex client_type. OAuth requirement is now
determined solely by client_type, eliminating the auth_type concept from the
LLM provider domain entirely.

- Add openai-codex to DB CHECK constraint (migration 0047) with data migration
- Add ClientTypeOpenAICodex constant and dedicated SDK/probe branches
- Remove AuthType from SDKModelConfig, ModelCredentials, TriggerConfig, etc.
- Simplify supportsOAuth to check client_type == openai-codex
- Add conf/providers/codex.yaml preset with Codex catalog models
- Frontend: replace auth_type selector with client_type-driven OAuth UI

---------

Co-authored-by: Acbox <acbox0328@gmail.com>
2026-03-27 19:30:45 +08:00
Acbox Liu 44c92f198b feat: introduce desktop app with Tauri (#296) 2026-03-27 18:08:42 +08:00
Acbox da2e999ce3 feat: searchable timezone select & bot timezone priority
- Add reusable TimezoneSelect component with search and UTC offset labels
- Replace plain Select with searchable TimezoneSelect in profile settings,
  bot settings, and browser context settings
- Move bot timezone setting from header dialog into bot settings tab
- Resolve timezone with bot > user > system priority for all LLM-facing
  time formatting (user message header, system prompt, heartbeat, tools,
  memory extraction)
- Format tool output timestamps (history, contacts) in resolved timezone
2026-03-26 21:00:21 +08:00
Yiming Qi 03ba13e7e5 feat: add timezone support for schedule and user runtime (#282) 2026-03-26 01:32:02 +08:00
Fodesu 3a7f5200ed fix(web): guard empty channel list in watch to prevent crash
The immediate watcher on configuredChannels accessed list[0].meta.type
without checking if the list was empty, causing a TypeError on initial
mount before data loaded. This crashed the component during setup and
corrupted KeepAlive state, making all bot detail tabs unresponsive.

Made-with: Cursor
2026-03-25 02:46:49 +08:00
Acbox ff764d53ac refactor: change npm package from @memoh to @memohai 2026-03-24 21:30:25 +08:00
Acbox 4ea1422409 chore: add issue templates 2026-03-24 19:27:43 +08:00
晨苒 e2e3b69acf feat(channel): add WeChat (weixin) adapter with QR code (#278)
* feat(channel): add WeChat (weixin) adapter with QR code

* fix(channel): fix weixin block streaming

* chore(channel): update weixin logo
2026-03-22 23:28:57 +08:00
Acbox 897cc32194 feat(web): add @memoh/icon package and unify brand icon system
Replace FontAwesome/CDN brand icons with local SVG-based Vue components
in a new shared @memoh/icon package. Provider icon URLs in conf/providers
YAML files are replaced with preset names, intercepted by ProviderIcon
component on the frontend. SearchProviderLogo and ChannelIcon components
are migrated to @memoh/icon. All icon containers now use a unified
circular gray (rounded-full bg-muted) style. Adds wechat and matrix
channel icons.
2026-03-22 22:07:32 +08:00
AlexMa233 609ca49cf5 feat: matrix support (part 1) (#242)
* feat(channel): add Matrix adapter support

* fix(channel): prevent reasoning leaks in Matrix replies

* fix(channel): persist Matrix sync cursors

* fix(channel): improve Matrix markdown rendering

* fix(channel): support Matrix attachments and multimodal history

* fix(channel): expand Matrix reply media context

* fix(handlers): allow media downloads for chat-access bots

* fix(channel): classify Matrix DMs as direct chats

* fix(channel): auto-join Matrix room invites

* fix(channel): resolve Matrix room aliases for outbound send

* fix(web): use Matrix brand icon in channel badges

Replace the generic Matrix hashtag badge with the official brand asset so channel badges feel recognizable and fit the circular mask cleanly.

* fix(channel): add Matrix room whitelist controls

Let Matrix bots decide whether to auto-join invites and restrict inbound activity to allowed rooms or aliases. Expose the new controls in the web settings UI with line-based whitelist input so access rules stay explicit.

* fix(channel): stabilize Matrix multimodal follow-ups and settings

* fix(flow): avoid gosec panic on byte decoding

* fix: fix golangci-lint

* fix(channel): remove Matrix built-in ACL

* fix(channel): preserve Matrix image captions

* fix(channel): validate Matrix homeserver and sync access

Fail Matrix connections early when the homeserver, access token, or /sync capability is misconfigured so bot health checks surface actionable errors.

* fix(channel): preserve optional toggles and relax Matrix startup validation

* fix(channel): tighten Matrix mention fallback parsing

* fix(flow): skip structured assistant tool-call outputs

* fix(flow): resolve merged resolver duplication

Keep the internal agent resolver implementation after merging main so split helper files do not redeclare flow symbols. Restore user message normalization in sanitize and persistence paths to keep flow tests and command packages building.

* fix(flow): remove unused merged resolver helper

Drop the leftover truncate helper and import from the resolver merge fix so golangci-lint passes again without affecting flow behavior.

---------

Co-authored-by: Acbox Liu <acbox0328@gmail.com>
2026-03-22 21:55:34 +08:00
Acbox Liu b3a39ad93d refactor: replace persistent subagents with ephemeral spawn tool (#280)
* refactor: replace persistent subagents with ephemeral spawn tool (#subagent)

- Drop subagents table, remove all persistent subagent infrastructure
- Add 'subagent' session type with parent_session_id on bot_sessions
- Rewrite subagent tool as single 'spawn' tool with parallel execution
- Create system_subagent.md prompt, add _subagent.md include for chat
- Limit subagent tools to file, exec, web_search, web_fetch only
- Merge subagent token usage into parent chat session in reporting
- Remove frontend subagent management page, update chat UI for spawn
- Fix UTF-8 truncation in session title, fix query not passed to agent

* refactor: remove history message page
2026-03-22 19:03:28 +08:00