Commit Graph
208 Commits
Author SHA1 Message Date
Aska 4be3826af7 chore: 清空 v2 实现,重建新架构骨架(人格化通用 Agent 运行时) 2026-09-05 23:09:26 +08:00
Aska 9c8d5a9e8d feat(rag): pgvector knowledge base with API and LLM tools
Cyrene CI / backend (push) Has been cancelled
Cyrene CI / frontend (push) Has been cancelled
- services/rag: knowledge_docs store — vector search via the shared
  embedder (HNSW index, graceful ILIKE fallback), list/delete scoped to
  the user, search intentionally global for the single-user deployment
- gateway: GET/POST /knowledge/docs, DELETE /knowledge/docs/:id,
  POST /knowledge/search
- plugins/knowledge: knowledge_search and knowledge_ingest tools so the
  persona can save and recall information mid-conversation
- main: migrations, store wiring, plugin registration
2026-08-21 18:40:01 +08:00
Aska ac0c2b2c73 feat(ai-core): real vision image analysis
- llm: Adapter.Vision sends multimodal chat requests (text + image_url,
  data URLs supported) and logs the call as purpose 'vision'
- gateway /images/analyze now accepts image_url or image_base64 and
  returns real analysis instead of a placeholder message
- main wires the default LLM adapter as the vision analyzer
- httptest coverage for the vision request/response shape
2026-08-21 18:33:44 +08:00
Aska 2104fc0c6c feat(frontend): voice input and read-aloud UI
- assistant messages get a 🔊 button that fetches TTS audio and plays
  it, toggling to stop
- ChatInput gains a mic button: MediaRecorder capture, base64 upload to
  /voice/stt, recognized text fills the input
- api client: voice.tts (blob) and voice.stt helpers
2026-08-21 18:31:24 +08:00
Aska a0357a7bbd feat(voice): real TTS fallback chain and whisper-compatible STT
- TTS providers: cloud (OpenAI-compatible /audio/speech, e.g. Bailian
  compatible mode with cosyvoice), local self-hosted HTTP server,
  edge-tts CLI, espeak CLI, silent — ordered by TTS_PROVIDER list,
  skipping providers whose binary/config is missing
- STT: whisper-compatible /audio/transcriptions endpoint (cloud or
  self-hosted faster-whisper), replacing the empty dashscope stub
- config: TTS_CLOUD_URL/KEY/MODEL/VOICE, TTS_LOCAL_URL, STT_API_URL/
  KEY/MODEL; cloud keys fall back to DASHSCOPE_API_KEY
- gateway /voice/tts now returns real audio/mpeg bytes instead of a
  byte count
- tests: cloud/local/whisper round-trips via httptest, chain skip
  behavior, fallback order; kept and adapted prior service tests
2026-08-21 18:28:39 +08:00
Aska b8fb7feb86 feat(ai-core): mood state machine and affection level
Cyrene CI / backend (push) Has been cancelled
Cyrene CI / frontend (push) Has been cancelled
- new emotion package: rule-based sentiment (positive/negative lexicon)
  drives mood transitions (开心/平静/难过) with 30min inactivity decay;
  affection 0-100 grows with positive interaction, with 初识→熟悉→信赖→
  羁绊 tiers
- pipeline records each user message and injects a mood line into the
  system prompt so the persona's tone follows her mood
- mood changes broadcast over WS; frontend shows a mood badge with
  affection tooltip; also handles the 'reminder' message type from the
  reminder scheduler
- tests: sentiment scoring, mood shift, affection bounds, prompt line,
  onChange callback
2026-08-21 18:13:23 +08:00
Aska 26d65dd6bb feat(frontend): message search and session export entry points
Cyrene CI / backend (push) Has been cancelled
Cyrene CI / frontend (push) Has been cancelled
- SearchModal queries GET /messages/search and jumps to the matching
  session; opened from the sidebar button or Ctrl+K
- session items in the sidebar gain a hover export button that
  downloads the markdown export via an authenticated fetch + blob
  (plain links cannot send the JWT)
2026-08-21 12:59:30 +08:00
Aska 9d040fde0b feat(plugins): implement web-search, web-fetch, http and file tools
- web-search: real SearXNG /search?format=json query, top-5 formatted
  results (was a 'not configured' stub)
- web-fetch: fetch page, strip scripts/styles/tags, truncate to 4000
  runes for the LLM context
- http: generic request tool (GET/POST/PUT/DELETE/PATCH) with scheme
  and method validation, status + truncated body
- file: sandboxed read/write/list inside the data directory with path
  escape rejection; split into file_read/file_write/file_list
- all tool schemas converted to proper JSON Schema; httptest/tempdir
  tests for each plugin
2026-08-21 12:57:19 +08:00
Aska d80710d85a feat(gateway): automation rule engine and reminder scheduler
- engine: 5-field cron parser (*/n, ranges, lists) firing at most once
  per minute; device-state triggers with edge detection; manual trigger
  via POST /automation/rules/:id/trigger; actions run through the AI
  pipeline so rules can call any tool (IoT control, search, ...)
- reminders: due-scan scheduler delivering via WebSocket broadcast,
  optional LLM-polished reminder text with plain-title fallback;
  Reminder gains Done flag with ListDue/MarkDone
- tests: cron matching and validation, once-per-minute dedup, device
  edge triggering, manual trigger, reminder delivery
2026-08-21 12:54:11 +08:00
Aska 9f30cdd086 feat(bridge): QQ adapter reconnect and send rate limiting
- supervisor loop keeps the OBv11 WebSocket alive, reconnecting with
  exponential backoff (1s→30s) when the connection drops; Start no
  longer fails permanently when NapCat is temporarily unreachable
- Send enforces MinGap between messages (from SendOptions or the
  adapter's send_interval_ms setting, now wired from the admin panel)
- parseMessage no longer panics on events missing sender/time fields
- tests: reconnect after drop, rate limit enforcement, malformed events,
  send while disconnected
2026-08-21 12:48:04 +08:00
Aska 8603839711 feat(ai-core): trace instrumentation, LLM thinker, decay scheduler
Cyrene CI / backend (push) Has been cancelled
Cyrene CI / frontend (push) Has been cancelled
- orchestrator: Tracer interface with spans for intent analysis, persona,
  subsession dispatch, context build, LLM streaming and each tool call;
  traces finish when the stream completes — the admin Trace waterfall
  finally receives data
- background: Thinker generates real LLM thoughts (post-chat + silence
  triggers, recent history as context, empty/overlong outputs discarded);
  thoughts broadcast to web clients as 'thinking' WS messages; pipeline
  postChatHook triggers post-chat thinking after each round
- memory: ApplyDecayAll + ListUserIDs with a 6h decay/purge cron in main
  (was implemented but never scheduled)
2026-08-20 20:57:27 +08:00
Aska 8495a4b055 feat(memory): hybrid vector search via embedder
- repository: optional pgvector embedding column (migration with
  CREATE EXTENSION guarded by main), SearchByVector cosine search,
  vector-enabled insert path
- service: SetEmbedder — memories are embedded on Add; Search merges
  vector hits with n-gram keyword matches (vector first, deduped)
- embedder was already implemented (OpenAI-compatible API + n-gram FNV
  fallback) but never instantiated; main now wires it from
  EMBEDDING_API_URL/EMBEDDING_MODEL config
2026-08-20 20:57:13 +08:00
Aska 8190007865 feat(frontend): session list sidebar and persisted history loading
Cyrene CI / backend (push) Has been cancelled
Cyrene CI / frontend (push) Has been cancelled
- Sidebar lists sessions with title/relative time, click to switch,
  hover-to-delete; refreshes after each round so new titles appear
- ChatPage loads message history from GET /sessions/:id/messages when
  entering a session
- WS connect now passes user_id so persisted messages have an owner
2026-08-20 20:34:08 +08:00
Aska f8196c111c feat(gateway): persist chat sessions and messages in PostgreSQL
- store: new chat_sessions/chat_messages tables with CRUD, ILIKE message
  search, and auto-titling from the first user message
- context: optional Persister on the sliding-window store — messages are
  saved asynchronously on Add, sessions not in memory are restored from
  the database on Get
- orchestrator: ProcessInput/FinishRound now carry userID so persisted
  messages have an owner
- api: real session handlers (list/create/delete), message history and
  clear endpoints, working message search and three-format export
  (markdown/txt/json), fixing the short-ID panic in export
- main: migration, store wiring, ctxStore persister adapter

Tests: chat store handler lifecycle (fake store), context persister
save/restore, stub auth login flow updated.
2026-08-20 20:34:08 +08:00
Aska f44bf26050 fix(build): stop ignoring cmd/cyrene sources
Cyrene CI / backend (push) Has been cancelled
Cyrene CI / frontend (push) Has been cancelled
The bare 'cyrene' .gitignore pattern matched the cmd/cyrene directory,
so trace_adapter.go was never committed and a fresh clone failed to
build (undefined: traceAdapter). Scope the pattern to the root binary
and add the missing file.
2026-08-20 19:42:32 +08:00
Aska cc040b861d feat(ai-core): trigger memory extraction after each conversation round
The WS hub and platform bridge now call Pipeline.FinishRound when the
response stream completes, recording the assistant reply and invoking
the LLM memory extractor asynchronously.
2026-08-20 19:40:58 +08:00
Aska 7c02d31194 feat(ai-core): wire function calling into the LLM pipeline
- llm: ChatStreamWithTools sends OpenAI-format tools; streamed tool_call
  deltas are reassembled by index into complete ToolCalls on the Done token
- model: LLMMessage gains ToolCallID/ToolCalls; StreamToken gains ToolCalls
- orchestrator: new ToolExecutor interface and streamWithTools loop —
  execute requested tools, feed results back, up to 3 rounds, final round
  forces a plain text answer; normal chats still stream token by token.
  Also adds Pipeline.FinishRound (assistant reply recording + post-round
  hook), wired to transports in the next commit.
- main: inject the plugin registry via toolExecAdapter

Includes an httptest-based test covering delta reassembly, tool
execution, and result feedback.
2026-08-20 19:40:58 +08:00
Aska 9a3c77dbd3 fix(bridge): align admin panel field keys with backend adapter settings
Frontend sent remote_url/bot_token/webhook_url while the backend reads
ws_url/token/listen_addr, so QQ adapters could never connect. Also add
the missing bot_qq field and wire the webhook adapter's APIKey.
2026-08-20 19:40:32 +08:00
Aska a58ec7325d refactor(logging): replace all print/log with structured slog logger
Cyrene CI / backend (push) Has been cancelled
Cyrene CI / frontend (push) Has been cancelled
- main.go: 30+ log.Printf → logger.Infof
- plugin/registry: 12 log.Printf → logger.Infof
- db/db.go, ws/hub.go: log → logger
- platform-bridge: fmt.Printf/println → logger.Info
- Logs now: time=... level=INFO msg=...
- 16 packages pass, vet clean
2026-08-12 21:31:06 +08:00
Aska 628d416dcd feat(admin): add authenticated restart endpoint + fix admin username
Cyrene CI / backend (push) Has been cancelled
Cyrene CI / frontend (push) Has been cancelled
- POST /api/v1/admin/restart: admin-only restart (forks new process)
- Fix: MemUserStore now uses cfg.AdminUsername instead of hardcoded 'admin'
- RestartFunc injected by main.go for clean process fork + exit
2026-08-12 21:26:58 +08:00
Aska dee48b6766 feat: add automation, reminders, notifications, msg search, session export, image analysis, host exec, PWA, Docker, E2E, CI/CD
Cyrene CI / backend (push) Has been cancelled
Cyrene CI / frontend (push) Has been cancelled
- Automation: rules CRUD (in-memory store + API)
- Reminders: CRUD (in-memory store + API)
- Notifications: push interface for future push server
- Message search: API endpoint with DB-backed query
- Session export: /sessions/:id/export → Markdown
- Image analysis: API stub for multimodal LLM
- Host exec: API stub for Docker sandbox
- PWA: manifest.json + service worker
- Docker: Dockerfile + docker-compose.yml
- E2E: Playwright test scaffold
- CI/CD: GitHub Actions workflow (go test + tsc)
2026-08-12 19:43:46 +08:00
Aska 3f9c4ca3c3 fix(prompt): prevent LLM from confusing context with user input
- Context merged into single system message with clear delimiters
- Prefix: 「以下是系统上下文,不是用户说的话」
- Memory → 【相关记忆】, IoT → 【设备状态】
- Filter empty memories, skip raw intent data
- Persona rule: context markers are internal data, not user input
2026-08-12 19:28:32 +08:00
Aska 585dfa1e38 fix(prompt): clean persona system prompt — remove YAML dump, filter empty subsessions
- Persona injector: concise natural language rules, not raw YAML
- Context builder: skip empty memory, skip raw intent data
- Prompt reduced from 2000+ tokens to ~500 tokens
- LLM response quality improved (natural tone, no confusion)
2026-08-12 19:27:12 +08:00
Aska 14a8eecfdb fix(memory): improve dedup thresholds and keyword priority
- Dedup: OR logic with 28%/0.45 thresholds (was 25%/0.4)
- Keywords: segments first → 3-grams → 2-grams
- False positive: 10% → acceptable level
- Accuracy: 80% correct dedup, 71% real rate
2026-08-12 19:20:14 +08:00
Aska dc3671eb8d feat(bench): add memory benchmark tool + export keywords
- tools/memory-bench: 6 metrics (write/search/dedup/keyword/bulk/rate)
- memory: export ExtractKeywordsPublic for benchmarking
- Results: 1000+ 条/秒 write, 380µs search, 80% dedup accuracy, 71% real rate
2026-08-12 19:15:15 +08:00
Aska 6a4887e52a feat(llm): add LLM call recording with admin panel integration
- llm.Adapter: SetCallLogger hook for recording every API call
- llm.CallLogger: ring-buffer with Recent+Stats for admin API
- main.go: wire DeepSeek adapter to CallLogger
- Fix: single CallLogger instance for both recording and display
- Metrics: model name, duration, success/fail, tokens
- All 16 packages pass
2026-08-12 19:10:51 +08:00
Aska 5b2bcc9441 fix(frontend): resolve TypeScript errors in TracePage
- Fix if-else missing semicolon (TS1005)
- Fix useRef missing initial value (TS2554)
2026-08-12 18:57:23 +08:00
Aska 4e2e81f684 feat(trace): waterfall visualization + persona YAML sync
- trace.Logger: Trace+Span model with 14+ hop tracking
- trace.SpanTimer: convenience API for instrumentation
- trace_adapter.go: serialize Trace+Span for frontend
- Frontend TracePage: colored waterfall bars, expand/collapse, detail popup
- persona.go: full v1 YAML parser (identity/traits/forbidden/sections)
- cyrene_persona.yaml: v1 persona config copied to v2
- Orchestrator: TraceHook + MemoryExtractor injection points
2026-08-12 18:52:39 +08:00
Aska 47047c903c feat(memory): add LLM-driven memory extraction from conversations
- memory/extractor: async LLM-based memory extraction from chat history
- Parses JSON lines from LLM response as memory entries
- Wire into orchestrator pipeline via PostProcess hook
- Non-blocking: runs in goroutine with 30s timeout
- Automatic dedup via existing keyword overlap logic
2026-08-12 18:43:04 +08:00
Aska 886fcf2216 fix(memory): rewrite dedup with n-gram keyword overlap + embedder
- Keyword extraction: 2-3 char sliding window + segment splitting
- Dedup: keyword overlap (>25%) OR Jaccard (>0.4) triggers merge
- SearchByNGrams: pgvector GIN index on keywords array
- Embedder: n-gram FNV hash (zero dep), OpenAI API with auto-fallback
- GIN index on keywords column for fast overlap search
- All tests pass
2026-08-12 18:24:04 +08:00
Aska ba42ea2b45 fix(bridge): add complete OBv11 fields matching v1 ethend
- OBv11: mode (client/server), remote_url, access_token, http_url,
  http_token, bot_port, send_interval_ms, admin_uids (8 fields)
- Telegram: bot_token, webhook_url, admin_uids
- Discord/Webhook: proper fields with labels
- Mode dropdown selector for client/server
- Field labels and placeholders matching v1
2026-08-12 18:12:39 +08:00
Aska 9eaed2883f feat(bridge): separate bridge config from .env, web panel + hot-reload
- BridgeConfigStore: file-backed JSON config (configs/bridge.json)
- Auto-creates config file only when user saves via admin panel
- Hot-reload: watches config file every 5s, reloads adapters live
- Admin API: GET/PUT/DELETE /api/v1/admin/bridge/config/:name
- Frontend: full CRUD page with platform type selector + toggle
- Removed bridge env vars from .env.example
2026-08-12 17:55:15 +08:00
Aska 217319eabc chore: add .env.example config template with all options
- Full config template with comments for every setting
- start.sh auto-loads .env if present
- Covers: LLM, DB, Auth, IoT, Voice, Platform Bridge, Search, CORS, WS
2026-08-12 17:46:23 +08:00
Aska 2a23ecdbdb fix(ui): remove blue background behind avatar image
- Remove bg-primary from avatar containers in Login/Chat/MessageList/Header
- Avatar image now fills container cleanly with object-cover
- Preserve shadow glow effect
2026-08-12 17:44:31 +08:00
Aska 5faa955bce feat(ui): add light theme with system auto-switch + Cyrene avatar
- Miuix day/night dual theme CSS variables
- themeStore: light default, follows prefers-color-scheme
- Header: sun/moon toggle button
- All components migrated to CSS variables
- Cyrene avatar image replaces 'C' logo everywhere
- Favicon added
2026-08-12 17:42:18 +08:00
Aska 78c5f0f1b0 chore: add cross-platform startup scripts
- start.sh: Linux/macOS一键启动 (编译+后端+前端+健康检查)
- start.bat: Windows批处理 (两个终端窗口)
- Ctrl+C优雅退出,环境变量可覆盖
2026-08-12 17:36:22 +08:00
Aska e8b5679cf4 feat(admin): add full-chain trace and performance monitoring
- Backend: trace.Logger ring-buffer for request chain events
- Backend: perf.Monitor with runtime.MemStats sampling every 10s
- Backend: /api/v1/admin/trace and /api/v1/admin/perf endpoints
- Frontend: TracePage — timeline with hop icons and status dots
- Frontend: PerformancePage — memory/GC bar charts + live stats
- Admin nav expanded to 11 items
2026-08-12 17:16:33 +08:00
Aska 8420691438 feat(admin): add model config CRUD and platform bridge pages
- Backend: ModelConfigStore with Provider/Model/Routing CRUD
- Backend: /api/v1/admin/models/config endpoints
- Frontend: ModelsPage with 3-tab editor (providers/models/routing)
- Frontend: BridgePage showing adapter status + group chat rules
- Admin nav expanded to 9 items
2026-08-12 17:13:29 +08:00
Aska 1a80ac2a00 feat(admin): add LLM call logs, system info, plugin list pages
- ai-core/llm: ring-buffer call logger with stats
- Gateway: /api/v1/admin/llm-calls, /system, /plugins, /sessions endpoints
- Frontend: LLMCallsPage (table + stats), SystemPage (version/plugins/sessions)
- Admin nav expanded to 7 items
2026-08-12 16:56:52 +08:00
Aska 8bfda096f7 feat(admin): rebuild admin panel with full management features
- AdminLayout: sidebar navigation (5 pages)
- Dashboard: real-time service/plugin/uptime stats
- Services: status display for all 4 services
- IoT Management: 8 devices with toggle controls
- Plugins: 11 plugins grid with type badges
- Memory: full CRUD with search, add, delete
- 60 modules, TS zero errors, 256KB JS
2026-08-12 16:45:21 +08:00
Aska bea29d3b73 style(frontend): redesign with Miuix HyperOS design language
- Color system: Miuix dark tokens (primary #277AF7, bg #242424, surface #000)
- Components: rounded-full buttons, squircle cards (18px), glass header
- Messages: blue user bubbles, dark AI bubbles with typing animation
- Admin dashboard: stat cards with real-time service status
- Login: centered logo with gradient shadow, HyperOS input fields
- Smooth transitions and scale-on-press interactions
2026-08-12 16:41:34 +08:00
Aska 17ef73bcbe feat(bridge): add multi-platform bridge — QQ, Telegram, Discord, Webhook
- platform-bridge: unified message model + Adapter interface
- qq/adapter: OBv11 WebSocket protocol with @mention detection
- telegram/discord: stub adapters with send capability
- webhook: HTTP POST receiver for generic webhook integration
- Router: message routing from platform → AI-Core → back
- Group chat rules: 500 char limit, 3s gap, silence keywords
- main.go: conditional adapter loading via env vars
2026-08-12 12:30:55 +08:00
Aska 7e3ec8da93 docs(api): add REST API reference and WebSocket protocol docs
- Docs/api/rest-api.md: all 15 endpoints with curl examples
- Docs/api/websocket.md: WS protocol, message types, reconnect strategy
2026-08-12 12:22:27 +08:00
Aska fbb331ed4b feat(auth): replace stub auth with real JWT + bcrypt
- RealAuthManager: JWT signing/validation + bcrypt password hashing
- MemUserStore: in-memory user store with default admin
- Register endpoint: user creation with hashed password
- Login endpoint: bcrypt verification + JWT generation
- AuthManager interface extended with Login/Register methods
2026-08-12 12:21:36 +08:00
Aska 6811480786 feat(gateway): wire real services into Gateway API handlers
- Router accepts full Dependencies (memory/voice/orchestrator/WShub)
- Memory API: CRUD + search endpoints with PostgreSQL persistence
- Voice API: STT/TTS endpoints
- Admin dashboard: real uptime + service status
- WebSocket chat: routes to AI-Core orchestrator pipeline
- APIAdapter bridges memory domain model to REST interface
- Smoke test: memory CRUD + session creation verified
2026-08-12 12:04:31 +08:00
Aska 4a71965686 feat(frontend): add React SPA with chat, auth, and admin pages
- Vite 6 + React 19 + TypeScript + Tailwind 4 + Zustand 5
- Login page with JWT auth
- Chat interface: MessageList, ChatInput, ChatContainer
- WebSocket hook with auto-reconnect and exponential backoff
- Sidebar with new chat button + session navigation
- Admin dashboard placeholder
- 57 modules, 242KB JS, TypeScript zero errors
2026-08-12 11:47:22 +08:00
Aska 192144563b feat(plugins): add 10 tool plugins and wire full service stack in main.go
- plugins: calculator, datetime, crypto, random, text, json, markdown
- plugins: web-search (SearXNG stub), web-fetch, file, http (stubs)
- main.go: full wiring — config→db→nats→plugins→voice→memory→
  persona→llm→context→subsession→orchestrator→gateway→ws
- 15 packages passing, 11 plugins loaded at startup
2026-08-12 11:37:36 +08:00
Aska 3b3e5a0697 feat(ai-core): add LLM orchestration engine
- model: shared data types (Message, Intent, StreamToken, LLMMessage)
- persona: YAML/Raw loading + system prompt injection
- llm: OpenAI-compatible adapter with streaming + semantic cache
- context: sliding window context store with token budgeting
- subsession: parallel provider dispatch + review message parser
- orchestrator: intent analysis pipeline (IoT/greeting/chat/memory)
- background: autonomous thinking engine
- 20+ tests, build + vet clean, ~130 total tests
2026-08-09 21:21:27 +08:00
Aska 99806fefad feat: add gateway API, voice service, WebSocket hub, and startup entry
- services/gateway/api: net/http router with JWT auth, stub login, 6 tests
- services/gateway/ws: WebSocket hub with echo support
- services/voice: STT/TTS provider chain with fallback, 6 tests
- cmd/cyrene/main.go: single binary startup, 108 tests total
- Smoke test: health check + login verified on :8080
2026-08-09 21:09:43 +08:00
Aska 81ebdb910c feat(memory): complete memory service with passing tests
- model: Memory struct with categories/decay/keywords
- repository: PG CRUD + keyword search + table migration SQL
- service: dedup (Jaccard), keyword extraction, decay formula
- 7 tests (3 DB integration + 4 unit), 96 total, vet clean
2026-08-09 20:51:01 +08:00