Commit Graph

501 Commits

Author SHA1 Message Date
Acbox f0517a3a1f fix: inbox indirectly push notidy item into context 2026-03-03 20:38:36 +08:00
Acbox f88827945f feat(web): add tool message ui for built-in tools 2026-03-03 17:50:21 +08:00
Acbox 8f3e763fe4 fix(web): sidebar overlap 2026-03-03 16:42:14 +08:00
Tosd a5099e04d4 fix(webhook): missing client import (#170)
Co-authored-by: Tosd0 <65720409+Sevenyine@users.noreply.github.com>
2026-03-03 16:02:20 +08:00
Quincy ba918dc8b9 style(sidebar): improve mobile responsive layout for multi-level sidebar (#172) 2026-03-03 16:01:54 +08:00
Menci b1925bf2be feat(telegram): use sendMessageDraft for streaming in private chats (#174)
* feat(telegram): use sendMessageDraft for streaming in private chats

Use Telegram Bot API 9.3's sendMessageDraft to stream partial messages
with smooth animation in private chats, replacing the sendMessage +
editMessageText approach. Group/channel chats keep the existing
edit-based streaming.

- Add sendTelegramDraft() for the sendMessageDraft API
- Detect private chats via conversation_type metadata in OpenStream
- Use 300ms throttle for drafts (vs 5s for edits)
- Send permanent messages at tool call boundaries and on final event
- Reset buffer atomically in StreamEventFinal to prevent duplicate
  messages when multiple final events fire (one per assistant output)

* test(telegram): improve draft mode test assertions

Add sendTextForTest hook for sendTelegramTextReturnMessage to enable
direct assertion of send calls. Clean up residual unused variables
and replace indirect assertions with explicit mock-based verification.
2026-03-03 16:01:18 +08:00
BBQ 7730096696 fix(containerd): restore CNI MASQUERADE after container restart (#167)
cni.Remove() failure on stale iptables state blocked the retry
cni.Setup(), leaving bot containers without SNAT/MASQUERADE.

- Ignore cni.Remove() error so retry Setup always runs
- Add global MASQUERADE rule in entrypoints as belt-and-suspenders

Closes #161
2026-03-03 16:00:46 +08:00
BBQ b6e7407e63 fix(web): prevent bot history horizontal overflow and pagination wrapping (#166)
Ensure long history message content can wrap without expanding layout width, and keep pagination summary and controls on a stable single line.
2026-03-03 16:00:21 +08:00
BBQ ee587b8ef5 fix(mcp): fix snapshot management and encapsulate locking (#169)
- Fix DeleteContainer FAILED_PRECONDITION by cleaning up stopped task
  entries before container deletion
- Fix CreateSnapshot leaving container in broken state: commit turns
  the active snapshot read-only, so the full cycle (stop → commit →
  prepare → delete → recreate → start) is now applied consistently
- Use context.WithoutCancel for atomic container replacement sequences
  to prevent cancelled HTTP requests from corrupting container state
- Use dctx for DB operations (recordSnapshotVersion/insertEvent) to
  avoid orphan snapshots in containerd without matching DB records
- Restart task + network after snapshot replacement, fixing Exec after
  CreateVersion where the container had no running task
- Extract replaceContainerSnapshot helper to deduplicate the prepare →
  delete → recreate → start pattern across three call sites
- Move snapshot list data fetching into Manager.ListBotSnapshotData to
  encapsulate per-container locking; remove exported LockBot method
- Use UnixNano for snapshot names to avoid second-precision collisions
2026-03-03 15:59:57 +08:00
Fodesu 78faee4a0e fix(web): fix legend overlapping with chart (#163) 2026-03-03 15:56:43 +08:00
Acbox Liu 5982bc6a42 feat: models import (#164) 2026-03-03 15:53:52 +08:00
RoomWithOutRoof 450cc30a9f fix(utils): preserve colon-containing values in tagsToRecord; align invalidFallback; add formatRelativeTime (#156)
* fix(utils): preserve colon-containing values in tagsToRecord; align invalidFallback across date formatters; add formatRelativeTime

**key-value-tags: fix value truncation on tags with colons**

`tagsToRecord` used `tag.split(':')` with array destructuring, so any
value containing `:` (e.g. a webhook URL `https://example.com/hook`)
was silently truncated to just the scheme.  Switch to `indexOf` so the
split happens only on the first colon, preserving the full value.

Example (before → after):
  `tagsToRecord(['hook:https://api.example.com/cb'])`
  before: `{ hook: 'https' }`  ← bug
  after:  `{ hook: 'https://api.example.com/cb' }`

Add `key-value-tags.test.ts` covering: simple pairs, URL values,
multi-colon values, empty key/value, round-trip with `recordToTags`.

**date-time: honour `invalidFallback` consistently**

`FormatDateOptions` declares `invalidFallback` but only
`formatDateTimeSeconds` ever read it — `formatDateTime` and `formatDate`
both collapsed a present-but-invalid date string into `fallback ?? ''`,
making it impossible for callers to distinguish "nothing was passed" from
"a bad string was passed".

Extract a shared `resolveInvalid(value, options)` helper (prefers
`invalidFallback`, then `fallback`, then the raw value) and apply it
uniformly.  Also refactor `formatDateTimeSeconds` to use the existing
`parseDate` helper, eliminating the duplicated `new Date` + `isNaN`
guard.  No externally visible behaviour change for previously valid
combinations; callers that relied on invalid dates falling through to
`fallback` keep working since `resolveInvalid` falls through to
`fallback` when `invalidFallback` is absent.

**date-time: add `formatRelativeTime`**

Chat and notification UIs commonly need relative timestamps ("3 minutes
ago", "yesterday").  The utility file has no such function.  Add
`formatRelativeTime(value, options?)` using `Intl.RelativeTimeFormat`
so the output respects the browser locale without hardcoded English
strings.  Thresholds: seconds < 60 s, minutes < 1 h, hours < 24 h,
days < 7 d, beyond that falls back to `toLocaleDateString()`.  Accepts
both ISO strings and `Date` objects.

Add `date-time.test.ts` covering all four exported functions including
`vi.useFakeTimers` assertions for `formatRelativeTime`.

* fix(utils): clean up formatRelativeTime after merge

Made-with: Cursor
2026-03-03 15:49:02 +08:00
Acbox Liu ea719f7ca7 refactor: memory provider (#140)
* refactor: memory provider

* fix: migrations

* feat: divide collection from different built-in memory

* feat: add `MEMORY.md` and `PROFILES.md`

* use .env for docker compose. fix #142 (#143)

* feat(web): add brand icons for search providers (#144)

Add custom FontAwesome icon definitions for all 9 search providers:
- Yandex: uses existing faYandex from FA free brands
- Tavily, Jina, Exa, Bocha, Serper: custom icons from brand SVGs
- DuckDuckGo, SearXNG, Sogou: custom icons from Simple Icons

Icons are registered with a custom 'fac' prefix and rendered as
monochrome (currentColor) via FontAwesome's standard rendering.

* fix: resolve multiple UI bugs (#147)

* feat: add email service with multi-adapter support (#146)

* feat: add email service with multi-adapter support

Implement a full-stack email service with global provider management,
per-bot bindings with granular read/write permissions, outbox audit
storage, and MCP tool integration for direct mailbox access.

Backend:
- Email providers: CRUD with dynamic config schema (generic SMTP/IMAP, Mailgun)
- Generic adapter: go-mail (SMTP) + go-imap/v2 (IMAP IDLE real-time push via
  UnilateralDataHandler + UID-based tracking + periodic check fallback)
- Mailgun adapter: mailgun-go/v5 with dual inbound mode (webhook + poll)
- Bot email bindings: per-bot provider binding with independent r/w permissions
- Outbox: outbound email audit log with status tracking
- Trigger: inbound emails push notification to bot_inbox (from/subject only,
  LLM reads full content on demand via MCP tools)
- MailboxReader interface: on-demand IMAP queries for listing/reading emails
- MCP tools: email_accounts, email_send, email_list (paginated mailbox),
  email_read (by UID) — all with multi-binding and provider_id selection
- Webhook: /email/mailgun/webhook/:config_id (JWT-skipped, signature-verified)
- DB migration: 0019_add_email (email_providers, bot_email_bindings, email_outbox)

Frontend:
- Email Providers page: /email-providers with MasterDetailSidebarLayout
- Dynamic config form rendered from ordered provider meta schema with i18n keys
- Bot detail: Email tab with bindings management + outbox audit table
- Sidebar navigation entry
- Full i18n support (en + zh)
- Auto-generated SDK from Swagger

Closes #17

* feat(email): trigger bot conversation immediately on inbound email

Instead of only storing an inbox item and waiting for the next chat,
the email trigger now proactively invokes the conversation resolver
so the bot processes new emails right away — aligned with the
schedule/heartbeat trigger pattern.

* fix: lint

---------

Co-authored-by: Acbox <acbox0328@gmail.com>

* chore: update AGENTS.md

* feat: files preview

* feat(web): improve MCP details page

* refactor(skills): import skill with pure markdown string

* merge main into refactor/memory

* fix: migration

* refactor: temp delete qdrant and bm25 index

* fix: clean merge code

* fix: update memory handler

---------

Co-authored-by: Leohearts <leohearts@leohearts.com>
Co-authored-by: Menci <mencici@msn.com>
Co-authored-by: Quincy <69751197+dqygit@users.noreply.github.com>
Co-authored-by: BBQ <35603386+HoneyBBQ@users.noreply.github.com>
Co-authored-by: Ran <16112591+chen-ran@users.noreply.github.com>
2026-03-03 15:33:50 +08:00
RoomWithOutRoof 567a1f3761 feat(chat): show message timestamp (relative time, full datetime on hover) (#157)
- Add formatRelativeTime() to date-time utils (Intl.RelativeTimeFormat, locale-aware)
- Display relative time under each message in message-item.vue
- Show full datetime in title attribute on hover

Made-with: Cursor
2026-03-02 15:09:01 +08:00
RoomWithOutRoof 874ca5fac7 fix(web): add email channel icon (#158)
Email is a supported channel (bindings, providers, outbox) but had no icon
and fell back to the generic comment icon. Use FontAwesome envelope.

Made-with: Cursor
2026-03-02 15:08:49 +08:00
BBQ 802dfd995f feat(telegram): support custom API base URL for reverse proxy setups (#160)
Allow configuring a custom Telegram Bot API base URL (`apiBaseURL`) per
channel, enabling users behind restricted networks to route requests
through a reverse proxy (e.g. Nginx, Cloudflare Workers).

Both API calls and file downloads respect the configured endpoint.
When omitted, the official https://api.telegram.org is used.

Closes #159
2026-03-02 15:04:20 +08:00
Ringo.Typowriter d3edd17d90 feat(agent): loop detection (#152)
* feat(loop-detection): add configurable text and tool loop guards

* style(web): remove duplicate separator in bot settings
2026-03-02 15:00:09 +08:00
BBQ 04bce702b7 feat(devenv): MCP dev hot-reload with image-based approach (#145)
Add mcp-build.sh that compiles the MCP binary and packages it as an
OCI image layer on top of the base rootfs, imported directly into
containerd. Air triggers rebuild on code changes, cleaning stale
containers automatically.

Consolidate dev-only files (Dockerfiles, entrypoint, config, build
script) into devenv/ to separate dev tooling from production artifacts.
Skip image pull when already imported to speed up dev startup.
2026-03-02 14:59:48 +08:00
BBQ f9f968f13f feat(models): per-model probe testing with auto-detect UI (#133)
* feat(models): add per-model probe testing and auto-detect in UI

Move health probes from provider level to model level for precise
testing with real model_id and client_type. Provider test is now a
simple reachability check.

Backend:
- Add POST /models/:id/test endpoint that probes the model's provider
  using its actual model_id and client_type
- Add model healthcheck checker for bot health checks (chat/memory/embedding)
- Simplify provider test to reachability-only

Frontend:
- Auto-probe models on mount with status indicator (green/yellow/red dot + latency)
- Auto-probe provider reachability on load and on provider switch
- Fix missing faBolt icon registration
- Manual re-probe via refresh button

Closes #117

* fix(models): increase probe timeout to 15s for slow providers

Some providers (e.g. DashScope) exceed the 5s probe timeout, causing
false-negative "context deadline exceeded" errors. Increase per-probe
timeout to 15s and healthcheck overall timeout to 30s.

* fix(sdk): regenerate exports after merge conflict

Resolve duplicate SDK exports introduced by merge conflict resolution so the web build can compile again while preserving new model probe endpoints.
2026-03-02 14:59:15 +08:00
Ringo.Typowriter cfb5f660bc chore(editor): add Zed workspace settings aligned with VSCode (#154) 2026-03-02 14:56:57 +08:00
Acbox 7e1d587fa1 chore: add gallery in README 2026-03-01 18:41:36 +08:00
Acbox 97b0596cf3 chore: update README 2026-03-01 18:20:20 +08:00
Acbox dc6f9bee89 release: v0.2.0 v0.2.0 2026-03-01 18:04:54 +08:00
Acbox Liu e16304d065 docs: v0.2 (#155)
* docs: rewrite getting started documentation

- Overhauled getting started guide to align with current frontend UI and logic.
- Split getting started documentation into modular chapters covering providers, models, bots, containers, files, skills, MCP, channels, memory, subagents, heartbeats, and search/email providers.
- Updated sidebar and index page to reflect the new documentation structure.

Made-with: Cursor

* docs: fix lint error in en.ts

Made-with: Cursor

* docs: add Channels documentation category

- Created a new top-level documentation category 'Channels'.
- Added detailed configuration guides for Telegram, Feishu (Lark), and Discord.
- Included official documentation references for bot creation on each platform.
- Updated 'Getting Started' channel page and main index with links to the new guides.

Made-with: Cursor

* refactor: docs to v0.2

* docs: add Scheduled Tasks chapter to getting started

- Created schedule.md covering cron-based automation, fields, pattern reference, and execution flow.
- Added comparison table between Schedule and Heartbeat features.
- Updated sidebar navigation to include the new chapter.

Made-with: Cursor
delete
2026-03-01 18:01:03 +08:00
Acbox 25167cb456 feat(web): schedule page 2026-03-01 17:28:31 +08:00
Acbox d69daeff68 release: v0.2.0-beta.1 v0.2.0-beta.1 2026-03-01 16:31:06 +08:00
Acbox 521eb41b63 refactor(ui): color design 2026-03-01 15:04:52 +08:00
Acbox 111e8d8732 fix(web): chart can only display today's data 2026-03-01 14:39:23 +08:00
Acbox 05e8e66bb2 feat(web): file manager in chat page 2026-03-01 14:35:26 +08:00
Acbox b2349fab13 chore(web): remove search provider filter 2026-03-01 14:35:26 +08:00
斬風千雪 b82444759a fix(telegram): several fixes of typing action in stream message (#136) 2026-03-01 14:11:32 +08:00
Acbox 3ed89aeb1d fix(web): monoca overload 2026-03-01 02:48:52 +08:00
Acbox 0bcef0cae6 fix(web): lint 2026-03-01 02:40:58 +08:00
Acbox 8b98e7fba8 refactor(web): sidebar 2026-03-01 02:40:07 +08:00
Acbox Liu 0cdf822603 feat: token usage state (#153)
* feat: token usage state

* fix: typo
2026-03-01 02:19:07 +08:00
Acbox 443ede30b4 refactor(skills): import skill with pure markdown string 2026-02-28 23:07:44 +08:00
Acbox 21029f44c7 feat(web): improve MCP details page 2026-02-28 22:48:51 +08:00
Acbox e365e5545a feat: files preview 2026-02-28 21:45:30 +08:00
Acbox fab5ae6320 chore: update AGENTS.md 2026-02-28 21:13:55 +08:00
BBQ cc5f00355f feat: add email service with multi-adapter support (#146)
* feat: add email service with multi-adapter support

Implement a full-stack email service with global provider management,
per-bot bindings with granular read/write permissions, outbox audit
storage, and MCP tool integration for direct mailbox access.

Backend:
- Email providers: CRUD with dynamic config schema (generic SMTP/IMAP, Mailgun)
- Generic adapter: go-mail (SMTP) + go-imap/v2 (IMAP IDLE real-time push via
  UnilateralDataHandler + UID-based tracking + periodic check fallback)
- Mailgun adapter: mailgun-go/v5 with dual inbound mode (webhook + poll)
- Bot email bindings: per-bot provider binding with independent r/w permissions
- Outbox: outbound email audit log with status tracking
- Trigger: inbound emails push notification to bot_inbox (from/subject only,
  LLM reads full content on demand via MCP tools)
- MailboxReader interface: on-demand IMAP queries for listing/reading emails
- MCP tools: email_accounts, email_send, email_list (paginated mailbox),
  email_read (by UID) — all with multi-binding and provider_id selection
- Webhook: /email/mailgun/webhook/:config_id (JWT-skipped, signature-verified)
- DB migration: 0019_add_email (email_providers, bot_email_bindings, email_outbox)

Frontend:
- Email Providers page: /email-providers with MasterDetailSidebarLayout
- Dynamic config form rendered from ordered provider meta schema with i18n keys
- Bot detail: Email tab with bindings management + outbox audit table
- Sidebar navigation entry
- Full i18n support (en + zh)
- Auto-generated SDK from Swagger

Closes #17

* feat(email): trigger bot conversation immediately on inbound email

Instead of only storing an inbox item and waiting for the next chat,
the email trigger now proactively invokes the conversation resolver
so the bot processes new emails right away — aligned with the
schedule/heartbeat trigger pattern.

* fix: lint

---------

Co-authored-by: Acbox <acbox0328@gmail.com>
2026-02-28 21:03:59 +08:00
Quincy 7d392a1143 fix: resolve multiple UI bugs (#147) 2026-02-28 20:32:25 +08:00
Menci 8fba05584c feat(web): add brand icons for search providers (#144)
Add custom FontAwesome icon definitions for all 9 search providers:
- Yandex: uses existing faYandex from FA free brands
- Tavily, Jina, Exa, Bocha, Serper: custom icons from brand SVGs
- DuckDuckGo, SearXNG, Sogou: custom icons from Simple Icons

Icons are registered with a custom 'fac' prefix and rendered as
monochrome (currentColor) via FontAwesome's standard rendering.
2026-02-28 20:32:12 +08:00
Leohearts cf7d578005 use .env for docker compose. fix #142 (#143) 2026-02-27 19:06:59 +08:00
Acbox b47258b15e refactor(web): fix types, ui, error handling, unhealthy styles 2026-02-27 18:02:23 +08:00
BBQ bf0eeb0e80 feat(search): add 8 new search providers (#135)
* feat(search): add Sogou search provider

* fix(search): use new endpoint and API version for sogou

* feat(search): add Serper, SearXNG, Jina, Exa, Bocha, DuckDuckGo search providers

Add six new search provider integrations:
- Serper: Google search via Serper API
- SearXNG: Self-hosted meta search engine
- Jina: Jina AI search API
- Exa: Exa neural search API
- Bocha: Bocha AI web search
- DuckDuckGo: DuckDuckGo HTML search (no API key required)

Each provider includes backend implementation, config schema,
i18n entries, and Vue settings component.

* feat(search): add Yandex search provider

Add Yandex search provider with XML response parsing and
configurable search type (RU/TR/COM).

---------

Co-authored-by: Menci <mencici@msn.com>
2026-02-27 00:00:44 +08:00
斬風千雪 d4ad1597e3 fix(agent): force flush remaining text before call tools (#134) 2026-02-26 23:59:49 +08:00
Acbox dfcfc4aff4 chore(docs): add deepwiki badge 2026-02-26 23:45:48 +08:00
BBQ f68b675efd fix(containerd): normalize image references for containerd compatibility (#138)
Containerd does not auto-prepend "docker.io/" to short Docker Hub names
like "memohai/mcp:latest", causing it to treat "memohai" as a registry
host and fail with EOF. Add NormalizeImageRef() to ensure all image
references are fully qualified before being passed to containerd.
2026-02-26 20:22:36 +08:00
BBQ cedac8dbf6 chore: require config.toml for deployment, update docs (#139)
- docker-compose.yml now defaults to ./config.toml instead of
  conf/app.docker.toml, enforcing explicit configuration for
  production deployments (dev environment still uses conf/ directly)
- Update DEPLOYMENT.md and docs with clear instructions to copy
  config template before starting
- Update config-toml.md: add registry/cni fields, remove obsolete
  [brave] section (search providers are now managed via web UI),
  fix default values
- Add China mainland mirror documentation
2026-02-26 20:20:29 +08:00
Acbox Liu fe10abf3fc refactor: inbox (#137)
* refactor: inbox

* fix: migrations

* fix: migrations
2026-02-26 20:16:02 +08:00