Commit Graph
582 Commits
Author SHA1 Message Date
viettranx 0cffbf5bfa fix(agent): loop improvements, history compaction, config tweaks 2026-03-20 21:46:22 +07:00
viettranx 001fe2721c fix(files): fallback workspace search for generated file links
LLMs hallucinate file paths in responses (e.g. ./system/generated/file.png)
when the actual file is at /app/workspace/teams/.../generated/file.png.

Backend: /v1/files/ now falls back to searching the workspace directory
tree by basename when exact path isn't found. Generated filenames
(goclaw_gen_*) include nanosecond timestamps and are globally unique.

Frontend: relative file paths now use just the basename in the /v1/files/
URL, letting the backend fallback find the actual file. Auth token
appended as ?token= query param for authenticated file access.
2026-03-20 19:57:39 +07:00
viettranx ca6ec0bf9f fix(ui): add auth token to /v1/files/ requests in markdown file links
File preview dialog was showing {"error":"unauthorized"} because
fetch() calls to /v1/files/ lacked the Bearer token. Now appends
?token= query param (accepted by the files endpoint) to all resolved
file URLs including relative path detection.
2026-03-20 19:49:52 +07:00
Goonandviettranx 7040081756 feat(discord): add writer management commands (#309)
* feat(discord): add writer management commands (!addwriter, !removewriter, !writers)

Port Telegram's file writer commands to Discord with guild-wide scope.
Uses wildcard scope (guild:{guildID}:*) to match per-user contexts.
Also fixes system prompt injection to find guild-wide writers.

* fix(discord): use per-user scope for writer self-check

CheckPermission with guild-wide wildcard scope (guild:{guildID}:*)
fails to match auto-bootstrapped per-user perms. Use per-user scope
(guild:{guildID}:user:{senderID}) which matches both per-user exact
and guild-wide wildcard stored patterns via matchWildcard.

* fix(discord): deduplicate writers in prompt injection, add context timeout

- Deduplicate writers by UserID after merging guild-wide and per-user
  scope results in buildGroupWriterPrompt to prevent duplicates when a
  user has both grant types.
- Add 10s context timeout to Discord writer command handlers instead of
  using context.Background() to prevent DB calls from hanging.

---------

Co-authored-by: viettranx <viettranx@gmail.com>
2026-03-20 19:44:31 +07:00
viettranx cab9338f14 fix(ui): chat running status, streaming layout, file links, scroll jitter
- Add isBusy derived state (isRunning || teamTasks active) for stop button
  and top bar status — reflects team task activity after main agent completes
- Align ActiveRunZone with MessageBubble layout: bubble wrapper for streaming
  text, compact tool cards with divide-y borders
- Detect relative file paths (./path) in markdown and render as file chips
  routed through /v1/files/ endpoint
- Fix auto-scroll jitter during streaming by using instant scroll and
  ignoring programmatic scroll events in the near-bottom check
2026-03-20 19:27:51 +07:00
Le Dat c9a484d5d7 fix: Windows deployment — broken symlinks, missing packages, dep scanner false positives (#292)
fix: Windows deployment — broken symlinks, missing packages, dep scanner false positives

- Dockerfile: add pdfplumber, pdf2image, anthropic, poppler-utils, bash to ENABLE_FULL_SKILLS
- Dockerfile: resolve broken git symlinks from Windows clone (core.symlinks=false)
- Dockerfile: strip CRLF from docker-entrypoint.sh at build time
- .gitattributes: enforce LF line endings for shell scripts
- dep_scanner.go: track nested subdirectories + scripts dir basename as local modules
2026-03-20 18:54:45 +07:00
viettranx 11673dabf1 fix(agent): prevent trailing assistant messages for proxy provider compat
Reorder team task reminders to inject before the user message instead of
after, ensuring the user's message is always the last in the messages
array. Proxy providers (LiteLLM, OpenRouter) reject requests ending with
an assistant-role message (unsupported prefill).

Also add a safety net in the OpenAI provider to strip any trailing
assistant message that might slip through in the future.
2026-03-20 18:46:27 +07:00
viettranx 0415052872 fix(tools): strip tab indent from cron description, restore lost context
Remove leading tabs that wasted tokens in LLM system prompt.
Restore timezone example (Asia/Ho_Chi_Minh) and channel auto-fill info
that were dropped in #307.
2026-03-20 18:27:18 +07:00
chungtran4078andChung Tran 8b44c01627 Fix: agent call cron tool within invalid params (#307)
* fix: agent add cron within invalid params

* fix: sometime cron tool calling fail

---------

Co-authored-by: Chung Tran <chung.tran@diqit.io>
2026-03-20 18:24:37 +07:00
viettranx 7634bb7834 fix(telegram): use typed error checks for 5xx detection in retry/dedup logic
Replace loose string matching ("502", "503", "504") with telegoapi.Error
type assertion — prevents false positives from error messages that
happen to contain these substrings. Also classifies 5xx as
post-connect errors since the server received the request.
2026-03-20 18:24:00 +07:00
badgerbees 874923d44b fix(telegram): suppress duplicate messages on high-latency streaming connections (#286)
fix(telegram): suppress duplicate messages on high-latency streaming connections
2026-03-20 18:21:46 +07:00
viettranx 670b295851 fix(telegram): bounded concurrent handlers, stall-aware downloads, media error feedback
- Replace sequential polling dispatch with semaphore-bounded goroutines
  (max 20 concurrent handlers) to prevent polling hangs from slow media
  downloads without risking unbounded goroutine growth
- Add sync.WaitGroup for graceful shutdown — Stop() waits for in-flight
  handlers with a 15s timeout
- Add progressReader that aborts downloads stalled for 60s (no data)
- Return MediaError from resolveMedia so callers know what failed and why
- Annotate model content with error context when media is skipped
  (e.g. "[sent media (image) — skipped: exceeds 20 MB limit]")
- Send Telegram reply to user when their file is too large or download fails
- Use errMediaTooLarge sentinel in all size-check paths for consistent
  error classification
2026-03-20 18:18:51 +07:00
viettranx dba3f4e4e6 fix(agent): prevent "..." fallback when iteration budget exhausted
Add early detection and graceful degradation when the model exhausts its
iteration budget without producing a text response:

- Inject 75% budget nudge telling model to start summarizing
- Strip all tool schemas on final iteration to force text-only response
- Adaptive web_fetch maxChars (60K→20K→10K) via iteration progress context
- Bump DefaultMaxIterations 20→30 for web-research workloads
2026-03-20 17:55:51 +07:00
Viet Tran 84650c5c14 feat(teams): attachments refactor, semantic search, improved prompting (#310)
* feat(teams): refactor attachments, remove team_message, add task comments UI

Major team system refactoring:

- Drop team_workspace_files, team_workspace_file_versions, team_workspace_comments,
  team_messages tables; replace team_task_attachments with path-based schema
- Add denormalized comment_count/attachment_count on team_tasks for dashboard perf
- Auto-track file writes as task attachments via WorkspaceInterceptor
- Remove team_message tool entirely (tool, store, i18n, builtin_tools, MCP bridge)
- Members communicate via task comments; approve/reject use comments for audit trail
- Add commented/new_task notification types to TeamNotifyConfig
- Enrich task completion announce with member comments
- User-created tasks stay pending (backlog) — no auto-assign to leader
- Configurable member request tasks (member_requests.enabled in team settings)
- Structured task description template in TEAM.md for v2 leads
- HTTP attachment download endpoint with IDOR + path traversal protection
- Web UI: count badges on task list, comments section with input, download button
- Team settings UI: completed/commented/new_task toggles, member requests section

* feat(teams): priority dispatch, compact prompting, realtime comments

- Priority dispatch: DispatchUnblockedTasks dispatches only 1 task per
  owner per round (highest priority first). Fixes cancel bug where
  CancelSession killed innocent queued tasks.
- Prompt rework: Replace verbose Task Decomposition (25 lines) with
  compact Task Planning (8 lines). Add explicit UUID warning and
  sequencing guidance for weak models (Qwen, MiniMax).
- Recent comments in dispatch: buildRecentCommentsSummary appends 3
  most recent comments to re-dispatched tasks (reject, retry, stale).
- Enrich comment event payload with TaskNumber, Subject, CommentText
  (truncated 500 runes, UTF-8 safe).
- UI: Board subscribes to TEAM_TASK_COMMENTED for realtime comment_count
  badge updates. Task detail dialog auto-refreshes comments on event.
- Tool description hint: guide models to write self-contained task
  descriptions with clear objectives and context.

* perf(teams): add ListRecentTaskComments with SQL LIMIT

Dispatch only needs 3 most recent comments — avoid fetching all.
New ListRecentTaskComments(ctx, taskID, limit) uses ORDER BY DESC
LIMIT N then reverses to chronological order.

* feat(teams): add subject embedding for semantic task search + improve prompting

- Add vector(1536) embedding column to team_tasks with HNSW index
- Implement hybrid search: FTS (0.3) + cosine similarity (0.7) with graceful fallback
- Auto-generate embeddings on task create/update, backfill existing tasks on startup
- Wire embedding provider into PGTeamStore via gateway_setup
- Change FTS from OR to AND with prefix matching for precise keyword search
- Reduce search page size from 30 to 5 to save tokens
- Rename migration 000023 → 000024, bump RequiredSchemaVersion to 24
- Update TEAM.md hints: prefer search over list, batch task creation with blocked_by
- Add anti-pattern examples to prevent sequential task creation
2026-03-20 17:51:40 +07:00
viettranx eb318ad8c3 feat(ui): add toast notifications and loading spinners to all save/mutation buttons
- Add userFriendlyError() helper to hide 5xx errors from users
- Add Loader2 animate-spin to all save/update/create/delete buttons
- Add useMinLoading(600ms) to StickySaveBar for visible feedback
- Move toast notifications from components into hooks (single source)
- Remove inline saved/saveError state in favor of toast system
- Add toast to all mutation hooks: agents, channels, skills, builtin-tools,
  sessions, teams, storage, tts, cron, providers, config
- Add i18n toast keys for en/vi/zh across all namespaces
- Deduplicate toast calls in team board components
2026-03-20 15:06:57 +07:00
viettranx 8a3bbab4aa fix(telegram): use bracket notation for media in group history context
Model confused context-history media tags (<media:image>) with current
message media, triggering read_image on non-existent images. Change
lightweightMediaTags() to use descriptive brackets (e.g. [sent an image])
so LLMs can distinguish history descriptions from actionable media tags.
2026-03-20 14:41:44 +07:00
viettranx 38dfcf8bb0 feat(tools): add Defuddle extractor chain for web_fetch (#296)
Add Cloudflare Worker (fetch.goclaw.sh) as primary markdown extractor
with waterfall fallback to built-in HTML→Markdown converter.

Architecture:
- ExtractorChain pattern with quality gate (min 100 chars, 10 words)
- Settings stored in builtin_tools DB table (not config.json5)
- ResolveExtractorChain reads chain from context per-request
- InProcessExtractor delegates to fetchRawContent (full SSRF + domain
  policy checks on redirects)
- DefuddleExtractor with configurable base_url + timeout
- Seed default chain [defuddle, html-to-markdown] for new deployments
- Backfill migration for existing deployments

Web UI:
- Dedicated DnD extractor chain form on builtin tools page
- Drag-and-drop ordering, enable/disable per extractor
- Timeout + base URL config for Defuddle
- i18n support (en/vi/zh)
2026-03-20 14:21:46 +07:00
viettranx b2330086ad fix(agent): harden intent classify — stricter quickClassify, steer vs newTask split
- Reduce quickClassify threshold from 60 bytes to 15 runes to prevent
  false positives (e.g. "làm đơn giản thôi" no longer matches "thôi")
- Use utf8.RuneCountInString for accurate Unicode length check
- Replace substring match with whole-word boundary check to avoid
  false positives like "nonstop" matching "stop"
- Remove statusKeywords; only exact "?" is fast-pathed as status query,
  all other status queries go through LLM classification
- Increase LLM classify timeout from 5s to 10s
- Differentiate steer (inject into running loop) from newTask (queue
  behind active run) instead of treating both as mid-run injection
2026-03-20 13:42:19 +07:00
viettranx f90a5f0974 feat(ui): refactor Provider, Cron, Channels pages with modern UX
- Add detail pages with sticky headers, bordered overview sections,
  and advanced config dialogs for Provider, Cron, and Channels
- Add list-row components for compact list views (no card view)
- Add Provider detail route (/providers/:id)
- Add cron job edit capability (updateJob via CRON_UPDATE RPC)
- Split Channel config into essential (Overview tab) vs advanced (dialog)
- Remove Channel Config tab, merge essential fields into General tab
- Add ViewModeToggle shared component (used by Agent/Team pages)
- Add i18n keys for all new UI elements (en/vi/zh)
- Simplify provider-form-dialog to create-only mode
2026-03-20 13:04:52 +07:00
viettranx 6e94c5fdf8 fix(agent): review fixes for tool call prefix stripping (#259)
- Fix TrimLeft → TrimPrefix to strip only one underscore separator
- Add registryName to indexedResult for parallel path cache
- Use registryName for bootstrapToolAllowlist and loopDetector checks
- Add server-side sanitization for ToolCallPrefix input
- Remove dead chatMessages alias and unrelated ParseStripAssistantPrefill
- Remove orphaned stripAssistantPrefill i18n keys
- Add 13 unit tests for StripToolPrefix
2026-03-20 09:14:28 +07:00
HXD.VN ffb536861f feat(agent): tool call prefix stripping for proxy providers (#259)
* feat(agent): support tool call prefix stripping for proxy providers

Proxy providers like LiteLLM and OpenRouter may prepend a prefix to
tool call names returned by the model (e.g. "proxy_exec" instead of
"exec"). This broke tool policy validation, registry lookup, and
hardcoded name checks for "team_tasks" and "spawn" in both serial
and parallel execution paths.

Add per-agent toolCallPrefix configuration that strips the configured
prefix from incoming tool call names before registry resolution. The
stripping is applied at resolveToolCallName() which is called before
permission checks, registry execution, and spawn/team_tasks detection.

- Add StripToolPrefix() supporting literal ("proxy_") and template
  ("{tool_name}") patterns
- Add toolCallPrefix to ToolPolicySpec with backward compat from old
  "toolPrefix" JSON key
- Fix config save using spread operator to prevent dropping new fields
- Add UI input in Tool Policy section with i18n (en/vi/zh)

* chore: ignore AI tool config directories

Add .gemini/, .claude/, .opencode/ to .gitignore to prevent
committing user-specific AI tool configurations.
2026-03-20 09:10:06 +07:00
viettranx 89937edb22 fix(team): prevent task progress regression from model actions 2026-03-20 08:27:18 +07:00
viettranx 60995ff956 fix(skills): treat sibling .py files as local modules in dep scanner
The scanner only tracked subdirectories as local modules, so cross-file
imports like `from extract_form_field_info import ...` were incorrectly
reported as missing pip packages, causing install failures.
2026-03-20 08:26:52 +07:00
Thieu Nguyen 7f1f126091 fix(docker): make runtime dir creation non-fatal in entrypoint (#288)
On first start with a fresh Docker volume, mkdir for .runtime
subdirectories can fail due to a volume initialisation race condition,
causing the container to restart loop. The directories are only needed
for agent-installed packages (pip/npm), so the failure is non-fatal.
2026-03-20 07:53:29 +07:00
viettranx 9f80842bbc feat(telegram): add voiceguard error sanitization and STT concurrency control (#33)
Cherry-pick two features from PR #33:

- Voiceguard: intercept technical errors (rate limits, tool failures, exit codes)
  in voice agent replies and replace with user-friendly fallback messages.
  Configurable error markers and fallback templates via TelegramConfig.
- STT: shared HTTP client with connection pooling (sync.Once) and concurrency
  semaphore (max 4 concurrent calls) to prevent STT proxy overload.
2026-03-20 07:50:13 +07:00
viettranx a4a7a59b6a fix(sandbox): path isolation, DooD volume mounting, hints, and nginx DNS (#129, #136)
Address issues identified in PR #137 with a cleaner approach:

- Sandbox isolation: add SandboxCwd/ResolveSandboxPath helpers to map
  filesystem tool paths to agent-scoped container subdirectories,
  preventing cross-agent file access via read/write/edit/list tools
- DooD volume mounting: add resolveHostWorkspacePath with multi-strategy
  container ID detection (/proc/self/mountinfo, HOSTNAME, os.Hostname)
  and 5s timeout on docker inspect
- Sandbox hints: expand from 1 pattern (binary not found) to 6 patterns
  (permission denied, network disabled, read-only FS, missing file,
  resource limits) with MaybeFsBridgeHint for filesystem tools
- Nginx DNS: add Docker resolver (127.0.0.11) with dynamic upstream
  variable to handle backend container IP changes
- MCP args: switch from comma-separated to space-separated parsing
  with quote support for --flag="value with spaces" patterns
- Refactor: rename ExecTool.workingDir to workspace for consistency,
  extract sandbox.DefaultContainerWorkdir constant
2026-03-20 07:32:23 +07:00
viettranx a8fecfb3b1 refactor(ui): replace native window.confirm with ConfirmDialog for task deletion
Unify confirmation UX — task-list and board-container now use the shared
ConfirmDialog component instead of browser-native window.confirm().
2026-03-20 07:23:19 +07:00
Thieu Nguyenandviettranx d9dffc66e7 docs: restructure README — hub-and-spoke pattern, fix accuracy (#285)
* docs: restructure README with i18n, static diagrams, and accuracy fixes

Restructure:
- Reduce README from ~950 to ~280 lines (hub-and-spoke pattern)
- Move Project Status to CHANGELOG.md
- Add hero section: centered title, tagline, description, badges
- Add nav links: Documentation, Quick Start, Twitter/X (OpenFang pattern)
- Add Documentation table linking all docs.goclaw.sh sections
- Replace 3 mermaid diagrams with static images for consistent rendering

Accuracy fixes:
- Fix provider count: 13+ → 20+ (verified from gateway_providers.go)
- Fix "5-layer defense" → 5-layer permission system per policy.go
- Add missing features: Heartbeat, Scheduling/Cron, Observability
- Fix all docs URLs to docs.goclaw.sh hash routing
- Add VPS $5 minimum 2GB RAM note for Docker

Internationalization (30 languages, ZeroClaw coverage):
zh-CN, ja, ko, vi, tl, es, pt, it, de, fr, ar, hi, ru, bn, he,
pl, cs, nl, tr, uk, id, th, ur, ro, sv, el, hu, fi, da, nb
- Keep product feature names in English: Extended Thinking, Heartbeat
- Vietnamese README hand-tuned for natural phrasing

* docs: move translated READMEs to _readmes/ directory

Keep all 30 language translations but declutter the project root.
Fix relative links (_statics/, cross-language, main README) for new location.
Update main README language selector to point to _readmes/.

---------

Co-authored-by: viettranx <viettranx@gmail.com>
2026-03-20 07:10:47 +07:00
viettranx 71af1a6bdd fix(i18n): add missing zh locale keys for ChatGPT OAuth setup 2026-03-20 06:56:25 +07:00
Plateau Nguyen 43990c7e56 Fix ChatGPT OAuth setup wizard flow (#289) 2026-03-20 06:54:11 +07:00
Plateau Nguyen c1893c73d1 fix: normalize delete confirmation matching (#290) 2026-03-20 06:48:48 +07:00
viettranx cc43f78b4b fix(agent): correct within-turn duplicate tool call ID pairing in sanitizeHistory
Replace single-value idRemap with queue-based idQueue so multiple tool
results sharing the same original ID pair correctly in encounter order.
Previously the map overwrote on duplicates, causing the second result to
be dropped and a synthetic placeholder to be emitted instead.
2026-03-20 06:39:58 +07:00
badgerbeesandviettranx 55bc752773 fix(agent): handle duplicate tool call IDs in OpenAI-compatible transcripts (#283)
* fix(agent): handle duplicate tool call IDs with occurrence-aware sanitization

* refactor(agent): simplify duplicate tool call ID handling

Replace complex occurrence-aware queue system with simpler approach:
- uniquifyToolCallIDs: append runID+iteration+index to all IDs at
  response time, guaranteeing cross-turn uniqueness via UUID
- sanitizeHistory: simple seen-set dedup for legacy sessions with
  pre-existing duplicate IDs, no queue/counter logic needed
- Restore full problem description in sanitizeHistory docstring
- Add unit tests for both dedup paths and edge cases

---------

Co-authored-by: viettranx <viettranx@gmail.com>
2026-03-20 06:32:38 +07:00
viettranx eb39a46d57 fix: propagate IsError in parallel tool execution path
The squash merge of #291 missed the parallel tool execution path.
Tool errors running in parallel still displayed as "Done" instead
of "Failed" when reloading chat history.
2026-03-20 06:32:13 +07:00
chungtran4078andChung Tran 18211154d0 fix: correct tool calling error status display in chat history (#291)
Co-authored-by: Chung Tran <chung.tran@diqit.io>
2026-03-20 06:28:34 +07:00
viettranx e13db25919 fix(ui): wire drag-and-drop file upload in chat view
Lift file state from ChatInput to ChatPage so DropZone.onDrop can
append dropped files to the shared state. Previously drag-and-drop
showed the overlay but never passed files to the input.
2026-03-20 00:27:14 +07:00
badgerbees 9100f981d7 fix(providers): robust Gemini thought_signature detection and history mapping
Improves supportsThoughtSignature with providerType and model normalization.
Strengthens collapseToolCallsWithoutSig with TrimSpace and camelCase support
to handle 'Thinking=OFF' whitespace signatures and proxy key translations.
2026-03-20 00:14:33 +07:00
badgerbees bc16af3797 fix(agent): handle duplicate tool call IDs in OpenAI-compatible transcripts
Simplified approach to fix duplicate tool_call_ids that cause HTTP 400 on OpenAI-compatible APIs (OpenRouter, vLLM, DeepSeek).

- uniquifyToolCallIDs: appends runID+iteration+index to all IDs at response time, guaranteeing cross-turn uniqueness via UUID
- sanitizeHistory: simple seen-set dedup for legacy sessions with pre-existing duplicate IDs
- Anthropic guard: skips ID rewriting when RawAssistantContent is present
- Unit tests for both paths + edge cases

Closes #283
2026-03-20 00:10:52 +07:00
viettranx cb93559154 fix(channels): allow config field in channel instance updates
Add "config" to channelInstanceAllowedFields so channel config changes
from the UI are actually persisted to the database instead of being
silently dropped by the allowlist filter.
2026-03-19 23:47:51 +07:00
Goon 1454614ca8 feat: add MiniMax-M2.7 model, custom model input, combobox UX fix, mobile font-size audit (#282)
- Add MiniMax-M2.7 to minimax_native provider model list
- Fix combobox dropdown UX: show all options on re-focus instead of filtering by current selection
- Add allowCustom prop to combobox for typing custom model names not in the list
- Add i18n key useCustomModel for EN/VI/ZH
- Audit all raw input/select/textarea elements across web UI to use text-base (16px) on mobile, preventing iOS Safari auto-zoom on focus
2026-03-19 23:47:11 +07:00
viettranx 49540651af fix(ui): session title live update + solid card backgrounds
- Listen for session.updated event to update sidebar labels in-place
- Replace bg-muted/30 with bg-muted on chat cards so dotted background
  pattern does not bleed through
2026-03-19 23:34:57 +07:00
viettranx 4da85913a2 feat(chat): auto-generate conversation titles via lightweight LLM call
After the first agent run completes, generate a short title from the
user's message using a 10s/50-token LLM call. Title is stored in the
session label column and pushed to clients via session.updated event.
2026-03-19 23:34:45 +07:00
viettranx 24ad97af31 feat(agent): add read-only streak + same-result loop detection
Detect agents stuck in read-only loops (consecutive non-mutating tool
calls) and same-result patterns (identical outputs from different args).
Warns at threshold, force-stops at critical.
2026-03-19 23:34:34 +07:00
viettranx eec083c91a docs: add ErrorBoundary key + route params rules to CLAUDE.md 2026-03-19 22:39:41 +07:00
viettranx 886ef64aec feat(ui): delete chat conversation from sidebar
- Add deleteSession() to useChatSessions hook
- Trash icon on session rows (hover-reveal, always visible on mobile)
- Simple confirm dialog (no typing required)
- If active session deleted, switch to next or create new
- i18n strings for en/vi/zh
2026-03-19 22:39:34 +07:00
viettranx 45295bc75a fix(ui): eliminate full-page flash on chat session switch
Root cause: ErrorBoundary in AppLayout used key={location.pathname},
causing React to unmount/remount the entire page on every URL change.

- Add stableErrorBoundaryKey() that strips dynamic segments from pathname
- Merge /chat and /chat/:sessionKey into single /chat/:sessionKey? route
- Derive sessionKey from useParams() instead of duplicating into useState
  (dual state caused race condition: setState + navigate → B→A→B bounce)
- Move session reset from render-time setState to useEffect
- Only show loading spinner when messages array is empty
2026-03-19 22:38:06 +07:00
viettranx b80ee0ae43 feat(sandbox): hint LLM when tool/binary missing in sandbox container
Detect exit code 127 and "command not found" patterns in sandbox
execution paths and append a [SANDBOX] hint to the error output,
so the model can inform the user about sandbox environment limitations.

Only applies to sandbox execution — host paths are untouched.
2026-03-19 22:17:29 +07:00
viettranx 711395f81f fix(ui): chat polish — floating bar, dotted bg, tool icon, flash fix
- Chat input bar: floating with backdrop blur and rounded corners
- Chat thread: dotted background pattern matching kanban board
- Tool call cards: blue Wrench icon for completed (was green Check)
- Memo wrap ChatSidebar, SessionSwitcher, ChatThread to prevent re-renders
- Keep old messages visible during session switch to prevent flash
2026-03-19 21:47:46 +07:00
viettranx 8409db5890 feat(ui): adopt canonical WS session key format + channel filter
- buildNewSessionKey uses agent:{id}:ws:direct:{uuid} format
- sessions.list sends channel:"ws" to filter WS-only sessions
- isOwnSession supports both new and legacy key formats
- Read-only bar now floating with rounded corners
2026-03-19 21:47:35 +07:00
viettranx 6b747d7571 fix(sessions): auto-migrate legacy ws-{userId}-{ts} keys to ws:direct:{ts}
Runs idempotent regex migration at PGSessionStore init to convert
legacy WS session keys to canonical format. Handles multi-hyphen
userIDs (UUIDs) by matching last segment as timestamp.
2026-03-19 21:47:26 +07:00