819 Commits

Author SHA1 Message Date
Acbox a9a9f7e955 feat: add image generation model and generate_image agent tool
Bots can now be configured with an image generation model (must have
image-output compatibility). When set, the agent exposes a generate_image
tool that calls the model via Twilight AI SDK, saves the result to the
bot container filesystem, and returns the file path.

- Add image_model_id column to bots table (migration 0053)
- Update settings SQL queries, service, and types
- New ImageGenProvider tool provider in internal/agent/tools/
- Wire provider in both cmd/agent and cmd/memoh entry points
- Add image model selector to frontend bot settings with compat filtering
- Regenerate swagger, SDK types, and sqlc code
2026-04-03 01:17:34 +08:00
Acbox 7ce1306505 chore(deps): update twilight-ai 2026-04-03 01:17:34 +08:00
Acbox 52546bc91b feat(scripts): add OpenRouter models sync script
Pulls model list from OpenRouter API and auto-generates
conf/providers/openrouter.yaml with inferred compatibilities
(vision, tool-call, image-output, reasoning) from API metadata.
2026-04-03 01:17:34 +08:00
Acbox a73bac05fe fix(agent): skip tool injection for models without tool-call capability
Models that lack the "tool-call" compatibility flag now run without
tools, preventing provider errors when the model does not support
function calling.
2026-04-03 01:17:34 +08:00
Acbox a31995424c feat: add per-route message dispatch modes (inject/parallel/queue)
Introduce three inbound message handling modes for channel adapters:

- inject (default, /btw): when a route has an active agent stream,
  inject the new user message into the running stream via the SDK's
  PrepareStep hook between tool rounds. The message is interleaved at
  the correct position in the persisted round.
- parallel (/now): start a new agent stream immediately, running
  concurrently with any existing stream (preserves current behavior).
- queue (/next): enqueue the message and process it after the current
  stream completes.

Key components:
- RouteDispatcher: per-route state management with inject channel,
  task queue, and active-stream tracking.
- PrepareStep integration: drains inject channel between tool rounds,
  records insertion position via InjectedRecorder for correct
  persistence ordering.
- interleaveInjectedMessages: inserts injected user messages at their
  actual injection position within the persisted message round.
- Parallel mode isolation: /now streams do not interact with the
  dispatcher, preventing them from clearing another stream's active
  state.
2026-04-03 01:17:33 +08:00
Acbox 33b57ee345 feat: rename info to status, add /status slash command
Rename session info endpoint from /sessions/:id/info to /sessions/:id/status
and update frontend tab label accordingly. Add /status slash command that
displays current session metrics (message count, context usage, cache hit
rate, used skills) as formatted text in any channel.
2026-04-03 01:17:33 +08:00
Acbox b3c783fb0b feat: add session info panel with message count, context usage, cache stats, and skills
Add GET /bots/:bot_id/sessions/:session_id/info API endpoint that returns
per-session message count, latest input token usage with model context window,
aggregated KV cache hit rate, and skills invoked via use_skill tool calls.
Frontend Info tab in the right sidebar now displays this data in a compact
key-value layout with a context usage progress bar and clickable skill links.
2026-04-03 01:17:33 +08:00
zhangxx b308c27f74 feat(web): add sidebar collapse functionality (#314)
* feat: add Supermarket integration (MCP & Skill marketplace) (#309)

* feat: add Supermarket integration (MCP & Skill marketplace)

Backend:
- Add [supermarket] config section with base_url (default: supermarket.memoh.ai)
- Add SupermarketHandler with proxy endpoints for MCPs, Skills, and Tags
- Add install endpoints: POST /bots/:id/supermarket/install-mcp (creates MCP
  connection with env vars) and install-skill (downloads tar.gz, extracts to
  container via gRPC)
- Register handler in FX wiring, generate Swagger docs and TypeScript SDK

Frontend:
- Add /settings/supermarket route with Store icon in sidebar
- Create supermarket page with search, tag filtering, MCP and Skill sections
- Add MCP/Skill card components with tag badges and install buttons
- Add install dialogs: MCP (bot selector + env var form), Skill (bot selector)
- Add i18n entries for en.json and zh.json

* fix: improve supermarket install UX

- Create BotSelect component with avatar + name using UI Select
- Replace NativeSelect in install dialogs and usage page with BotSelect
- Change MCP install flow: navigate to bot detail MCP tab with pre-filled
  draft instead of direct install, letting users review before saving
- Move Supermarket sidebar entry between Browser and Usage

* web: remove supermarket page top tag selector bar

Drop the horizontal tag chips and getSupermarketTags fetch; keep
search and tag filter via card tag clicks with clearable badge.

* web: add homepage link to supermarket MCP and Skill cards

Show an external-link icon next to the card title when homepage is
available, opening in a new tab on click.

* refactor: move skills directory from .skills to skills and enrich prompt

- Change skills storage path from `/data/.skills` to `/data/skills`
- Add usage instructions and directory location to the Skills section
  in the system prompt

* feat(web): add Activity Bar and right sidebar panel to chat page

Replace the old file manager panel with a multi-tab right sidebar system:
- Activity Bar with Terminal, Files, and Info tabs
- Resizable right panel with tab switching
- Extract shared Terminal component from bot-terminal.vue
- Add bottom preview layout mode to FileManager
- Delete session button with confirmation dialog
- Fix FileManager scroll in flex column layout (min-h-0)

* feat(web): add session-type-aware UI for chat interface

- Make IM/heartbeat/schedule/subagent sessions read-only (hide input box)
- Render heartbeat user messages as info blocks with trigger metadata and
  link to heartbeat logs
- Render schedule user messages as info blocks with task metadata and
  link to schedule settings
- Render subagent user messages as full-width markdown boxes
- Add clickable spawn task results to navigate to subagent sessions

* feat(web): add sidebar collapse functionality

- Add SidebarRail for edge drag-to-collapse interaction in both sidebars
- Center align icons when collapsed in bot list and settings sidebar
- Hide text labels and dropdown menus in collapsed state
- Keep create bot button in header

* fix(web): ensure secondary sidebar remains visible after page refresh

When the primary sidebar was collapsed, refreshing the page would cause
the secondary sidebar (e.g., providers list) to disappear.

The MasterDetailSidebarLayout had its own SidebarProvider but didn't
set default-open, causing it to read the same sidebar_state cookie
and follow the primary sidebar's collapsed state.

Fix by explicitly setting :default-open="true" on the secondary
SidebarProvider to ensure it always stays expanded.

---------

Co-authored-by: Acbox Liu <acbox0328@gmail.com>
2026-04-03 01:17:32 +08:00
Acbox e59fe9205b feat(web): add tabs layout and submit button to Supermarket page
Reorganize Supermarket into a tabbed UI with Skills as the first tab
and MCP as the second tab. Add a GitHub submit button in the header
linking to https://github.com/memohai/supermarket.
2026-04-03 01:17:32 +08:00
enpitsulin 8281a60d45 fix: enable mise monorepo root config (#316) 2026-04-03 01:17:31 +08:00
Acbox c3b2ede0ce feat(web): add session-type-aware UI for chat interface
- Make IM/heartbeat/schedule/subagent sessions read-only (hide input box)
- Render heartbeat user messages as info blocks with trigger metadata and
  link to heartbeat logs
- Render schedule user messages as info blocks with task metadata and
  link to schedule settings
- Render subagent user messages as full-width markdown boxes
- Add clickable spawn task results to navigate to subagent sessions
2026-04-03 01:17:31 +08:00
Acbox c0490c9688 feat(web): add Activity Bar and right sidebar panel to chat page
Replace the old file manager panel with a multi-tab right sidebar system:
- Activity Bar with Terminal, Files, and Info tabs
- Resizable right panel with tab switching
- Extract shared Terminal component from bot-terminal.vue
- Add bottom preview layout mode to FileManager
- Delete session button with confirmation dialog
- Fix FileManager scroll in flex column layout (min-h-0)
2026-04-03 01:17:31 +08:00
Acbox bb14bcb3bc refactor: move skills directory from .skills to skills and enrich prompt
- Change skills storage path from `/data/.skills` to `/data/skills`
- Add usage instructions and directory location to the Skills section
  in the system prompt
2026-04-03 01:17:31 +08:00
Acbox Liu faaf13a0e9 feat: add Supermarket integration (MCP & Skill marketplace) (#309)
* feat: add Supermarket integration (MCP & Skill marketplace)

Backend:
- Add [supermarket] config section with base_url (default: supermarket.memoh.ai)
- Add SupermarketHandler with proxy endpoints for MCPs, Skills, and Tags
- Add install endpoints: POST /bots/:id/supermarket/install-mcp (creates MCP
  connection with env vars) and install-skill (downloads tar.gz, extracts to
  container via gRPC)
- Register handler in FX wiring, generate Swagger docs and TypeScript SDK

Frontend:
- Add /settings/supermarket route with Store icon in sidebar
- Create supermarket page with search, tag filtering, MCP and Skill sections
- Add MCP/Skill card components with tag badges and install buttons
- Add install dialogs: MCP (bot selector + env var form), Skill (bot selector)
- Add i18n entries for en.json and zh.json

* fix: improve supermarket install UX

- Create BotSelect component with avatar + name using UI Select
- Replace NativeSelect in install dialogs and usage page with BotSelect
- Change MCP install flow: navigate to bot detail MCP tab with pre-filled
  draft instead of direct install, letting users review before saving
- Move Supermarket sidebar entry between Browser and Usage

* web: remove supermarket page top tag selector bar

Drop the horizontal tag chips and getSupermarketTags fetch; keep
search and tag filter via card tag clicks with clearable badge.

* web: add homepage link to supermarket MCP and Skill cards

Show an external-link icon next to the card title when homepage is
available, opening in a new tab on click.
2026-04-03 01:17:31 +08:00
Acbox 49e5f3d8ae release: v0.6.3 v0.6.3 2026-04-03 01:16:47 +08:00
Acbox 3fa311c6cb fix(media): proxy ContainerFileOpener through fallback storage provider
The fallback provider introduced in 5aeb2fd3 wrapped containerfs but did
not implement storage.ContainerFileOpener, causing IngestContainerFile to
fail with "provider does not support container file reading". This broke
outbound file attachments on all IM channels (Telegram, Discord, etc.)
because container paths like /data/xxx.xlsx were passed as-is to the
platform API instead of being ingested into the media store first.
2026-04-03 01:14:20 +08:00
Acbox 5aeb2fd3fc fix(media): add local filesystem fallback and fix gallery lightbox matching
- Add localfs storage provider as fallback when containerfs is unreachable
- Wrap media service with fallback provider in both entry points
- Fix gallery lightbox src matching by comparing pathnames only
2026-04-03 00:01:49 +08:00
Acbox fc2b603018 fix(agent): skip tools for models without tool-call capability and parse image output
- Add SupportsToolCall to RunConfig; only inject tools into SDK when set
- Update twilight-ai to 497ad09 which adds SSE scanner 10MB buffer
  (fixes token-too-long on large image payloads) and parses the images
  array from OpenAI-compatible chat completions into StreamFilePart
2026-04-03 00:01:14 +08:00
Acbox 574bc1fb59 release: v0.6.2 v0.6.2 2026-04-02 01:52:40 +08:00
Acbox c1e6e0cc7a feat(agent): add pagination and smart collapsing to container list tool
Large directories like node_modules/.venv could return thousands of entries,
wasting tokens and causing timeouts. Add offset/limit pagination to ListDir
RPC and collapse heavy subdirectories (>50 items) into summaries in recursive
mode. Collapsing runs at the bridge layer before pagination so the page window
reflects the collapsed view.
2026-04-02 01:51:19 +08:00
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 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
Acbox 72316d4040 docs: update gallery 2026-03-30 21:32:02 +08:00
Ran 49613a283b release: v0.6.0 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
AlexMa233 dd13e89469 Enhance Matrix bot setup documentation (#308)
* Enhance Matrix bot setup documentation

Added instructions for obtaining an access token using the Matrix Client Login API and clarified the importance of keeping it secret. Updated details on bot capabilities and linked to the roadmap for future features.

* Add warning about access token security

Added important note about keeping the access token secret.
2026-03-29 21:26:22 +08:00
Acbox Liu 5f42fed8e0 docs: v0.6 (#304)
* docs: v0.6

* docs: update readme
2026-03-29 20:30:21 +08:00
Acbox 23d7bfa4e0 fix(ci): handle pre-release version for Windows MSI bundle
WiX MSI only supports numeric-only versions (X.Y.Z). When the tag
contains a pre-release identifier (e.g. 0.6.0-beta.5), override the
MSI version via `bundle.windows.wix.version` with the stripped numeric
portion while keeping the full semver for other bundle formats.
2026-03-29 20:26:51 +08:00
Acbox bff9055d28 release: v0.6.0-beta.5 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
AlexMa233 c93ddc3a87 chore: use browser in devenv docker compose files by default (#306) 2026-03-29 20:13:22 +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 4ec4c76f9c fix(ui): remove unwanted borders on CollapsibleContent children
The child-selector border styles (*:border-b *:border-x etc.) on
CollapsibleContent caused unexpected white outlines around thinking
blocks and tool-call detail panels in chat messages.
2026-03-29 19:48:19 +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 86d83108d9 fix: use readline-capable shell for interactive terminal sessions
Container terminals were echoing raw ANSI escape sequences (^[[A, ^[[B,
etc.) instead of handling arrow keys because /bin/sh (dash/ash) lacks
readline support. Two changes fix this:

1. Bridge execPTY now directly exec's bare paths (e.g. /bin/bash) instead
   of always wrapping through "/bin/sh -c", preserving readline behavior.
2. Terminal handler detects bash/zsh in the container and prefers them
   over /bin/sh for interactive PTY sessions.
2026-03-29 19:31:24 +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 fc1ef4ddb3 fix(ci): sync version from git tag to Tauri build artifacts
Tauri desktop artifacts were always named with hardcoded version 0.1.0
(from tauri.conf.json) instead of the actual release version. Extract
the version from the git tag and update tauri.conf.json and Cargo.toml
before building.
2026-03-29 18:50:56 +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 90d5cc8fb2 fix: upgrade twilight-ai to fix Anthropic image media_type validation
Bumps twilight-ai to 3ebcc56 which strips data URL prefixes and
validates media_type before sending to Anthropic API, preventing
400 errors for unsupported image MIME types.
2026-03-29 18:16:47 +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