Commit Graph

637 Commits

Author SHA1 Message Date
ZhenYi
867f216a1f feat(theme): add preset color schemes and theme token system
Add 9 preset themes (Midnight, Forest, Sunset, Rose, Lavender,
Arctic, Nord, Dracula, Clean Light) with full palette definitions.

Implement theme token encoding/decoding algorithm:
- Token format: "T1:" + base64url(minified JSON)
- Share any theme via copyable token string
- Import themes by pasting tokens
- Only 16 core color fields encoded (badge classes derived)
2026-04-29 09:50:13 +08:00
ZhenYi
907b5ee3bf fix(room): fix file upload missing /api prefix and credentials
Upload URL was missing /api prefix causing 404, and missing
credentials: 'include' for cookie-based authentication.
2026-04-29 09:40:58 +08:00
ZhenYi
bba35f1b2c fix(room): increase streaming timeout from 60s to 120s
Some checks failed
CI / Rust Lint & Check (push) Has been cancelled
CI / Rust Tests (push) Has been cancelled
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
Give more buffer for heartbeat chunks to arrive during long tool
execution, reducing false "Stream timed out" errors.
2026-04-29 09:03:33 +08:00
ZhenYi
03f97c9221 fix(agent): spawn tool execution in separate task for heartbeat
Move tool execution to a spawned task so synchronous git2 operations
don't block the tokio worker thread, allowing heartbeat chunks to be
sent every 10s during long tool execution.

Also add analysis-first reasoning prompt to system messages.
2026-04-29 09:03:29 +08:00
ZhenYi
30822bbd7d fix(skill): support bare repo scanning via git tree traversal
Add scan_repo_tree_for_skills and scan_skills_from_tree functions that
traverse git objects directly instead of filesystem, enabling skill
discovery in bare repositories created via git2::Repository::init_bare.
2026-04-29 09:03:22 +08:00
ZhenYi
b673c31485 feat(fctool): register new git tools in mod.rs
Register repo_analysis, kb, and repo_util tool modules in the
git_tools register_all function.
2026-04-29 09:03:13 +08:00
ZhenYi
a5704c9730 feat(fctool): add repo utility tools for AI
Add repo_search, repo_readme, repo_commit_log, repo_contributors,
and repo_diff_summary function call tools for AI to search code,
read README, query commit history, list contributors, and diff revisions.
2026-04-29 09:03:03 +08:00
ZhenYi
4ef0d5b570 feat(fctool): add knowledge base tools for AI
Add repo_doc_index, repo_doc_read, and repo_doc_search function call
tools for AI to index, read, and search through documentation repos.
2026-04-29 09:02:56 +08:00
ZhenYi
5f12b07120 feat(fctool): add repo analysis tools for AI
Add repo_overview, repo_file_tree, repo_languages, and repo_dependencies
function call tools for AI to quickly analyze repository structure,
language breakdown, and dependency manifests.
2026-04-29 09:02:51 +08:00
ZhenYi
c2b4553537 feat(client): generate API client SDK with auto-generated exports
Some checks are pending
CI / Rust Lint & Check (push) Waiting to run
CI / Rust Tests (push) Waiting to run
CI / Frontend Lint & Type Check (push) Waiting to run
CI / Frontend Build (push) Blocked by required conditions
2026-04-29 00:06:30 +08:00
ZhenYi
7ce113a765 feat(agent): paginated model catalog with pricing + redesigned Add AI panel
Backend:
- New GET /api/agents/models/catalog endpoint with page/per_page/search
  params, excludes deprecated models, returns pricing data via
  model→version→pricing join
- ModelWithPricingResponse includes input_price, output_price, currency
- ModelListResponse with pagination metadata (total, page, per_page)
- Batch-fetches default versions + latest pricing to avoid N+1

Frontend:
- RoomSettingsPanel: replace Dialog with inline two-step panel
  - Step 1: paginated model browser with search, shows context length,
    max output tokens, pricing per 1K tokens, capability/modality badges
  - Step 2: selected model info card + AI configuration form
- Removed Dialog import and related unused dependencies
2026-04-28 23:58:46 +08:00
ZhenYi
bc1bdd8491 fix(room): never expose AI model UID to frontend
Backend:
- room_ai_list: batch-fetch models, skip entries where model_name
  cannot be resolved (instead of falling back to "AI {uid}")
- room_ai_upsert: return None for model_name when lookup fails
  (instead of "AI {uid}")

Frontend:
- room-context: discard configs with missing modelName after retries
- DiscordMemberList: filter out configs without modelName
- MessageInput: filter out configs without modelName
- RoomSettingsPanel: prefer model_name from API, fallback to
  availableModels lookup, never render raw UID
- RoomAiTasksPanel: fix broken id/name mapping (was cfg.id/cfg.name
  which don't exist), filter out configs without model_name
2026-04-28 23:21:45 +08:00
ZhenYi
5351df773b fix(api): register skill routes inside project scope to fix 404
Some checks are pending
CI / Rust Lint & Check (push) Waiting to run
CI / Rust Tests (push) Waiting to run
CI / Frontend Lint & Type Check (push) Waiting to run
CI / Frontend Build (push) Blocked by required conditions
In actix-web, separate web::scope() trees don't merge. The /projects
scope was intercepting /api/projects/{name}/skills before the separate
skill scope could match, causing 404 on all skill endpoints.

Move skill routes into init_project_routes as /{project_name}/skills/*
and remove the standalone configure(skill::init_skill_routes) call.
2026-04-28 22:58:57 +08:00
ZhenYi
108dd714d3 fix(room): include @user mentions in AI prompt context
Some checks are pending
CI / Rust Lint & Check (push) Waiting to run
CI / Rust Tests (push) Waiting to run
CI / Frontend Lint & Type Check (push) Waiting to run
CI / Frontend Build (push) Blocked by required conditions
- Extend extract_mention_context to handle user mentions
- Both @[repo:xxx] and @[user:xxx] are now included in AI context
2026-04-28 22:25:25 +08:00
ZhenYi
76e3d19cf5 fix(room): require @ai mention to trigger AI response
- process_message_ai now returns early if no @ai mention is found
- Verify mentioned AI exists in the room before responding
2026-04-28 22:21:12 +08:00
ZhenYi
55d33862f6 fix(room): support multiple AIs per room in should_ai_respond
- Add get_room_ai_configs() to fetch all AI configs for a room
- Check all AI model IDs against @ai mentions
2026-04-28 22:16:04 +08:00
ZhenYi
46a0bdc21e fix(room): should_ai_respond only triggers on @ai mention 2026-04-28 22:14:10 +08:00
ZhenYi
c2c079c74d fix(room): invert use_exact logic so it controls all-message mode
Previously: use_exact=false → respond to all messages (wrong default)
Now: use_exact=true → respond to all messages; use_exact=false → only @ai
2026-04-28 22:10:21 +08:00
ZhenYi
db0a2eca16 feat(ssh): add complete SSH server implementation for Git operations
- Implement SSHandle struct with comprehensive Git service handling capabilities
- Add support for multiple authentication methods including password, public key and certificate
- Integrate Git command parsing and execution with proper channel management
- Implement branch protection rules enforcement during Git operations
- Add robust error handling and logging for SSH connections and Git processes
- Create secure Git command execution with environment isolation
- Implement proper resource cleanup for channels and subprocesses
- Add support for receive-pack, upload-pack and upload-archive services
- Integrate with existing authz and database services for permission checks
- Implement proper data forwarding between SSH channels and Git processes

fix(config): improve environment loading with error reporting

- Replace silent dotenv loading failures with informative error messages
- Handle global config race conditions safely during application startup
- Improve config loading reliability and debugging capabilities

fix(link-unfurl): handle server-side rendering compatibility

- Add undefined window object check for SSR environments
- Prevent client-side only code from breaking server-side rendering

refactor(agent): improve tool registry error handling

- Replace panics with graceful error logging for duplicate tool registrations
- Add proper error type definitions for tool registry operations
- Implement safe merging of registries with duplicate detection

fix(room-context): enhance WebSocket connection reliability

- Add proper error handling for room subscription operations
- Improve connection management with better error suppression
- Add console warnings for debugging connection issues

feat(ws-client): add comprehensive WebSocket client implementation

- Create RoomWsClient class with complete WebSocket communication layer
- Implement request-response pattern with timeout handling
- Add support for various room-related events and actions
- Include proper connection status tracking and management
- Implement callback system for different event types
- Add automatic reconnection and error recovery mechanisms
2026-04-28 21:29:34 +08:00
ZhenYi
b3fb027848 fix(git): deduplicate skills by repo_id+blob_hash in hook sync
- Apply same deduplication logic as service scanner
- Keep latest version by commit_sha when duplicates found
- Fix type error: Ok("skill.md") → Some("skill.md".to_string())
2026-04-28 21:28:19 +08:00
ZhenYi
2db7934596 fix(skill): deduplicate skills by repo_id+blob_hash
- Change deduplication key from slug to {repo_id}+{blob_hash}
- Keep latest version by commit_sha when duplicates found
- Use git2 to open repos and get correct workdir and commit_sha
- Fix case-insensitive SKILL.md detection in scanner
2026-04-28 21:27:38 +08:00
ZhenYi
18917b6de1 feat(room): 修改 AI use_exact 默认值为 true
Some checks are pending
CI / Rust Lint & Check (push) Waiting to run
CI / Rust Tests (push) Waiting to run
CI / Frontend Lint & Type Check (push) Waiting to run
CI / Frontend Build (push) Blocked by required conditions
- room/src/ai.rs: use_exact 默认值从 false 改为 true
- 新增 migration: m20260428_000002_default_use_exact_true
2026-04-28 20:00:12 +08:00
ZhenYi
aab9f0dbf1 feat(frontend): 替换全屏loading动画为SVG逐帧绘制动画
- 新增 loading-animation.tsx 组件,从 public/load.html 转换
- 动画特性: SVG路径逐条绘制 + 渐变填充,最少展示1.5秒
- 替换 homepage/layout.tsx, workspace/redirect.tsx, protected-route.tsx 中的全屏加载
- 修复 sidebar-user.tsx 中 Invitations 按钮在缩回状态下的居中问题
2026-04-28 19:59:31 +08:00
ZhenYi
4571d4d042 fix(service): 修复扣费结果类型处理
- service/agent/billing.rs: 适配新的 BillingResult 枚举类型
- 将 InsufficientBalance 错误转换为 AppError::BadRequest
2026-04-28 19:59:17 +08:00
ZhenYi
c6bb72682b fix(agent): 修复扣费链路并实现级联扣费策略
- billing.rs: 修复参数传递 (model_id -> version_id)
- billing.rs: 新增 BillingResult 枚举支持 InsufficientBalance 错误
- billing.rs: 实现级联扣费 (优先 project 余额,不足时 fallback 到 workspace)
- billing.rs: 余额不足时创建系统消息并持久化
- chat/service.rs: 捕获 InsufficientBalance 错误并调用 create_system_message
- client/mod.rs: 超时时间从 60s 改为 120s
2026-04-28 19:59:06 +08:00
ZhenYi
13523762aa fix(fctool): 修复 git tools 中的类型不匹配问题
- blob.rs: 修复 resolve_oid 返回 commit OID 而非 blob OID 的问题
- tree.rs: 修复 git_tree_ls_exec 直接传递 commit OID 给 tree_list 的问题
- 所有修改使类型合约与 git domain API 匹配
2026-04-28 19:58:52 +08:00
ZhenYi
d1ade2c3c3 feat(deploy): add HPA autoscaling rules for all services except email
Some checks are pending
CI / Rust Lint & Check (push) Waiting to run
CI / Rust Tests (push) Waiting to run
CI / Frontend Lint & Type Check (push) Waiting to run
CI / Frontend Build (push) Blocked by required conditions
Add HorizontalPodAutoscaler (autoscaling/v2) using CPU and memory utilization
metrics to all deployment templates: app, static, gitserver, git-hook,
operator, adminrpc. Email-worker is excluded as requested.

- CPU target: 80% average utilization
- Memory target: 80% average utilization
- Each service has per-service min/max replicas in values.yaml
- Operator autoscaling defaults to disabled (enabled: false)
- Conditional via {{ if .Values.<service>.autoscaling.enabled }}
2026-04-28 13:42:37 +08:00
ZhenYi
b3e4cb7c7a docs(changelog): add April 28 entry for semantic search and tag vectorization
Some checks are pending
CI / Rust Tests (push) Waiting to run
CI / Frontend Lint & Type Check (push) Waiting to run
CI / Frontend Build (push) Blocked by required conditions
CI / Rust Lint & Check (push) Waiting to run
Update changelog with new features: semantic search for messages and tags,
room-scoped search, and incremental tag indexing. All 4 languages (en/cn/de/fr).
2026-04-28 13:15:58 +08:00
ZhenYi
a34cd73fdf fix(frontend): update search API types and fix IMEditor stale closure
Add room/pn search params to SearchMessagesData type definition.
Fix stale closure issue in IMEditor useEditor's onUpdate callback.
2026-04-28 13:12:42 +08:00
ZhenYi
5a90a475a4 feat(migrate): add content_tsv backfill migration for full-text search
Populate content_tsv column on existing messages for PostgreSQL FTS support.
2026-04-28 13:12:38 +08:00
ZhenYi
3643991955 fix(triage): improve AI issue triage with better prompt and label handling 2026-04-28 13:12:34 +08:00
ZhenYi
0acacbf57c feat(search): add room-scoped message search with project name filter
Add room parameter (UUID) and pn (project name) to search/messages API.
Service layer supports filtering messages by room and project scope.
Frontend search page updated with room-scoped search support.
2026-04-28 13:12:29 +08:00
ZhenYi
bbeaea6614 fix(billing): remove old billing module, delegate to record_ai_session
Billing is now handled internally by chat_service.process via record_ai_session.
Remove the old billing.rs file and explicit record_ai_usage calls from all 4
AI streaming modes (nonstreaming, react_nonstreaming, react_streaming, streaming).
2026-04-28 13:12:25 +08:00
ZhenYi
2a9ec6d509 feat(tag): vectorize repo tags after hook sync with incremental embedding + FC tool
- HookWorker gains optional embed_service field
- Captures changed tag names during webhook dispatch, batch-embeds after completion
- HookService auto-inits EmbedService from config for standalone git-hook binary
- Adds agent dep to git crate (no circular dep)
- SSH/HTTP servers no longer call start_worker (dedicated git-hook handles it)
- git_tag_search FC tool for agent semantic tag search with project isolation
2026-04-28 13:04:10 +08:00
ZhenYi
62727a93a1 feat(service): trigger Qdrant embedding on issue/repo/skill creation
- After issue_create: spawn embed_issue_chunked (non-blocking)
- After skill_create/update: spawn embed_skill
- After repo create/update in fctool: spawn embed_repo
- Wire EmbedService through AppService, available for all triggers
2026-04-28 13:04:04 +08:00
ZhenYi
93ec515f29 feat(room): batch-embed all room messages into Qdrant on persist
- make_persist_fn now accepts embed_service, collects persisted text messages
- Filters non-text, non-empty, non-system/tool messages
- Groups by room→project_name, batch-embeds via embed_memories_batch
- Removes old per-message synchronous embed_memory call
- Workers thread embed_service through to persist_fn
2026-04-28 13:03:59 +08:00
ZhenYi
026f5cf32d feat(context): thread embed_service through ToolContext for FC tool access
Add with_embed_service() builder and embed_service() accessor to ToolContext,
wired through ChatService so function-calling tools can access Qdrant vector search.
2026-04-28 13:03:55 +08:00
ZhenYi
bfdb934443 feat(embed): add chunked embedding, batch memory embed, and tag vectorization support
- chunk_text(): char-boundary-safe text chunking at paragraph/sentence breaks (7000 char limit)
- embed_memories_batch(): groups messages by room, batch-embeds all texts to reduce Qdrant calls
- embed_issue_chunked(): auto-chunks long issue bodies
- embed_skill(): upgraded with auto-chunking via chunk_text
- TagEmbedInput struct for batch tag embedding
- embed_tags_batch() / search_tags() with project isolation
- ensure_collections() now creates embed_repo_tag collection
2026-04-28 13:03:51 +08:00
ZhenYi
32d7b3b902 fix(billing): use actual tokens in nonstreaming ReAct billing
- ai_react_nonstreaming now passes real input/output tokens to billing
- Was passing hardcoded 0,0 despite destructuring token data
- Also fix unused variable warnings
2026-04-28 11:06:57 +08:00
ZhenYi
64ca5eeea1 fix(room): improve AI label fallback to never show "Unknown AI"
Fallback chain: modelName -> short model ID (no provider) -> 'AI'
2026-04-28 11:01:51 +08:00
ZhenYi
8a6ec1f62f fix(billing): add transaction isolation and fix race conditions
Critical fixes:
- Wrap balance updates in database transactions with SELECT FOR UPDATE
- Move history insert after balance validation to prevent orphaned records
- Use Decimal throughout to avoid silent conversion failures
- Prevent concurrent requests from causing negative balances

Tasks resolved:
- Task #4: Silent Decimal conversion failures
- Task #5: Missing transaction isolation (race conditions)
- Task #6: History inserted before validation
2026-04-28 10:12:24 +08:00
ZhenYi
6edacbcdf2 fix(billing): track actual tokens in ReAct mode instead of hardcoded 0/0
- process_react now returns (String, i64, i64) tuple with token counts
- Extract token stats from rig Agent FinalResponse usage field
- Both streaming and non-streaming ReAct modes now bill correctly
2026-04-28 10:04:54 +08:00
ZhenYi
7f927a4b6b fix(billing): pass real project_id instead of Uuid::nil() for cost calculation 2026-04-28 09:57:45 +08:00
ZhenYi
211cf0ee3e fix(agent): calculate and record cost in ai_session table
- Add record_ai_session() helper calling billing::record_ai_usage()
- Replace all Set(None) cost/currency with actual calculated values
- Cost computed from model_pricing via Decimal precision
2026-04-28 09:50:44 +08:00
ZhenYi
7b43f55f41 refactor(fctool): add descriptions to tools and simplify model sync
- Add description field to all fctool file and git tools
- Simplify extract_model_name in sync.rs (use upstream id directly)
2026-04-28 09:43:15 +08:00
ZhenYi
da2853d0ec fix(blob): use TextDecoder for proper UTF-8 decoding
- atob() returns Latin-1 binary string, not UTF-8
- Chinese characters decoded incorrectly causing mojibake
- Use TextDecoder("utf-8") with Uint8Array for correct handling
2026-04-28 09:42:52 +08:00
ZhenYi
21d0d1eae6 fix(commits): compute total count on cache miss for pagination
- git_commit_log now computes count when Redis cache misses
- Previous: returned total: 0 when cache empty
- Now: compute + cache on miss (5min TTL)
2026-04-28 09:42:47 +08:00
ZhenYi
ddd24bfb6d fix(streaming): add seq field for strict chunk ordering
- Add seq: u64 to RoomMessageStreamChunkEvent
- Frontend sorts by seq on insert for ordered replay
- Initial event now includes seq: 0
2026-04-28 09:42:41 +08:00
ZhenYi
5b3a6700be refactor(agent): replace custom ReAct loop with rig::agent::Agent
- Use AgentBuilder for native tool-calling with stream_prompt()
- Add RecordingTool wrapper preserving retry + DB recording
- Fix tool_choice bug in do_completion (same as call_stream_once)
- Add seq field to RoomMessageStreamChunkEvent for strict ordering
- Map streaming events: Text→Answer, Reasoning→Thought, ToolCall→Action
- Only final event has done=true, removed premature stream ending
- Store __chunks__ JSON in thinking_content for ordered replay
2026-04-28 09:42:36 +08:00
ZhenYi
2bd40aee1b fix(room): clear AI stream state on room switch and hide cursor for saved chunks
- Clear activeAiStream, streamingChunks, and timers when room changes
- Add showCursor prop to OrderedStreamChunks — only show cursor
  during active streaming, not for saved content
2026-04-27 22:57:18 +08:00