- atob() returns Latin-1 binary string, not UTF-8
- Chinese characters decoded incorrectly causing mojibake
- Use TextDecoder("utf-8") with Uint8Array for correct handling
- 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
- Clear activeAiStream, streamingChunks, and timers when room changes
- Add showCursor prop to OrderedStreamChunks — only show cursor
during active streaming, not for saved content
Create changelog page with language tabs (EN/CN/DE/FR),
timeline layout, and MDX rendering. Add generate script
to build changelog data from mdx files.
- issue_triage.rs: use check_project_access instead of nonexistent get_project_member
- email/lib.rs: make EMAIL_REGEX pub to suppress dead_code warning
- tracing_fmt.rs: minor import ordering cleanup and code formatting
- Import room_message_reaction, room_message_edit_history, room_notifications modules
- Fix room_message_edit_history: no Room column, use subquery via messages
- Change publish_project_room_event from Result to () handling
- Add QuerySelect import for limit() method in workers.rs
- Add Offline status to ModelStatus enum
- Sync marks all models offline first, then activates found ones
- Deduplicate by model name (ignoring provider)
- Deactivate orphaned models (offline -> deprecated)
- Add models_offline and models_deactivated to SyncModelsResponse
- Add deduplicate_existing_models() for cleanup
- Rename upsert_model to upsert_model_by_name
- commits.tsx: fix Unix timestamp (time_secs) not multiplied by 1000
- RoomMessageSearch.tsx: add explicit generic type for resp.data
- RoomPinPanel.tsx: make sender_id optional (string | null)
- message-list.tsx: remove unused index variable in map
- repository-context.tsx: use correct RepoInfo field names
- use-audio-recording.ts: use audioStream state instead of undefined var
- universal-ws.ts: rename unused id to _id
- Reject secrets shorter than 32 bytes (fall back to generated key)
- Use SHA-256 hash instead of naive byte cycling to derive the key
(cycling "password" to 64 bytes gave extremely low entropy)
- Start SSH rate limiter cleanup task that was missing (prevent memory leak)
- Create single ToolContext outside tool execution loop so max_tool_calls
and max_depth guards actually fire across batch tool calls (was creating
fresh context per call, bypassing all limits)
- Fix second copy of push_subscription unwrap that was in a
tokio::spawn block with different indentation
- Replace constant UUID parse unwrap with expect()
- SSH rate limiter: wire SshRateLimiter into SSHServer with IP-based
rate limiting on new_client connections
- Room startup: cap initial room load at 1000 via limit() to prevent
resource exhaustion on large instances
- WS token exposure: only include token in URL for cross-origin
connections; same-origin web clients authenticate via secure cookies
- CSRF: confirmed SameSite::Lax + Secure + HttpOnly are all set
(session config defaults)
Resolves GLIBC_2.39 mismatch error — CI builds on ubuntu-latest
(24.04) which links against glibc 2.39, but debian:bookworm-slim
only provides glibc 2.36, causing binary execution failure.
Clear wsToken on auth-related close codes (3000-4999), connection
timeout, and after 3 consecutive reconnect failures so the next connect
attempt fetches a fresh token. Add onRoomAiUpdated and onRepoChanged
callbacks that re-fetch AI configs and repo list when pushed via WS.
Fix AI member list to never display raw UUID.
Add 'repo' to MentionType across all editor types, include repos in the
@ trigger pool, add repo badge (green chip), Repos section in the
mention dropdown, and MentionBadge styles. Wire projectRepos from
room context into IMEditor mentionItems.
When a user mentions a repository in room chat, extract the repo name
from @[repo:name:label] brackets, look up the full repo model from the
database, and inject its details (name, description, default branch,
visibility) into the AI message context. Works independently of
embed_service availability.
Add RoomAiUpdated, RepoCreated, RepoUpdated, RepoDeleted event types.
Publish RoomAiUpdated after room_ai upsert/delete and repo events
after repo create/update. Always set model_name in AI list response
(fallback to "AI {uuid}" when model lookup fails) so frontend never
displays a raw UUID.
When APP_AI_BASIC_URL already ends with /v1 (e.g. openrouter.ai/api/v1),
appending /v1/models produces /v1/v1/models. Detect trailing /v1 and
only append /models in that case.
Move git_tools, file_tools, and project_tools from libs/service into a
new libs/fctool crate with correct workspace dependencies. Fixes the
rev.len() >= 40 bug in all git tool resolve functions (OID check needs
exact 40-char hex, not just >= 40). Adds 4 new git blob tools
(blob_get, blob_exists, blob_content, blob_create). Fixes parameter
naming inconsistency in repos.rs and adds project_name to list_repos
output. Removes unused excel/pdf/ppt/word file tools.