Commit Graph
983 Commits
Author SHA1 Message Date
Huy Doan 72025698bb fix(sandbox): support write_file append in FsBridge (#650)
- Add appendMode bool param to FsBridge.WriteFile (>> vs >)
- Pass appendMode through sandbox path in WriteFileTool
- EditTool always uses overwrite mode (false)

Closes #650
2026-04-03 16:03:57 +07:00
viettranx 80c2c0e0ee fix(providers): normalize Ollama api_base URL to include /v1 suffix
- Write-time normalization via normalizeOllamaAPIBase() on create/update
- Read-time safety net in resolveAPIBase() for pre-existing DB records
- Covers both ProviderOllama and ProviderOllamaCloud
- Stop hardcoding +"/v1" in registerInMemory/startup registration

Closes #654
2026-04-03 15:44:39 +07:00
Kai (Tam Nhu) Tran 9050426840 fix(providers): add reasoning field alias for Ollama thinking models (#658)
- Add `reasoning` JSON alias to openAIMessage and openAIStreamDelta structs
- Coalesce reasoning/reasoning_content in streaming and non-streaming parse paths
- reasoning_content remains canonical; reasoning is Ollama-specific fallback

Closes #655
2026-04-03 15:31:46 +07:00
viettranx 78a2152053 refactor(http): split provider_models.go into focused modules
- provider_models.go (154L): types, handler, reasoning helpers
- provider_models_fetch.go (191L): remote API fetchers (Anthropic, Gemini, OpenAI, Ollama)
- provider_models_catalog.go (103L): hardcoded model lists

All files under 200-line guideline. No logic changes.
2026-04-03 15:18:54 +07:00
Kai (Tam Nhu) Tran e8579f5e1c feat(providers): add rich Ollama model listing via /api/tags (#659)
- Ollama/OllamaCloud providers now use native /api/tags for richer metadata
- Display name built from family + parameter_size + quantization_level
- Strips /v1 suffix, DockerLocalhost support, graceful fallback on error
- 7 comprehensive tests covering all edge cases

Closes #656
2026-04-03 15:17:08 +07:00
viettranx bde95b70c5 fix(providers): clamp max_tokens to 4096 for Fireworks non-streaming requests
Fireworks AI requires stream=true for max_tokens > 4096. Proactively
clamp non-streaming requests to avoid 400 errors (their error format
doesn't match the generic clampMaxTokensFromError retry regex).

Closes #660
2026-04-03 15:04:45 +07:00
viettranx 3206c266bf fix(docker): bump claude-code pin to ^2.1.91
Previous pin ^1.0.47 was stale — latest is 2.x series.
2026-04-03 14:55:44 +07:00
Duc Nguyen 532aab4387 fix(docker): pin Python/npm dependency versions (#663)
- Add docker/requirements-base.txt (edge-tts) and requirements-skills.txt (10 packages)
- Pin versions: pip ~= (patch only), npm ^, anthropic >=0.88<2.0
- Add .npmrc with supportedArchitectures for Alpine musl builds
- Restore --frozen-lockfile (lockfile regenerated with musl entries)
- Pin @anthropic-ai/claude-code@^1.0.47

Closes #662
2026-04-03 14:55:07 +07:00
ila 943b2eb3e5 feat(docker): make goclaw-ui stop instantly (#665) 2026-04-03 14:42:47 +07:00
viettranx 9472819334 fix(memory): skip user_id filter in shared memory queries
When share_memory is enabled, memory queries now remove the user_id
filter entirely instead of filtering by user_id IS NULL. This matches
the existing KG shared behavior and allows all users to see all memory
documents (global + per-user from everyone).
2026-04-03 14:34:29 +07:00
viettranx 1f85c73a39 fix(ui): resolve raw user IDs to display names across web UI
Extract shared formatUserLabel util and wire useContactResolver into
15 pages that previously showed raw numeric IDs (e.g. 386246614)
instead of human-readable names.

- Add formatUserLabel with display hierarchy: name > @username > #id
- Fix MultiUserPicker badges (covers all allow/deny lists)
- Fix permissions, tenant users, overview cards, traces, nodes
- Remove redundant raw ID spans from permissions and pending messages
- Delete duplicate formatScopeLabel/parseUserDisplay local functions
2026-04-02 23:30:14 +07:00
viettranx ade6c7ba33 fix(agent): preserve MediaRefs when merging consecutive same-role messages
sanitizeHistory now appends MediaRefs from dropped messages so compaction
summary retains knowledge of shared media files.
2026-04-02 22:58:35 +07:00
Michael Nguyen d79d738148 fix(agent): clear RawAssistantContent on dedup + merge consecutive same-role messages
sanitizeHistory dedup rewrites ToolCalls IDs but not RawAssistantContent.
Anthropic provider prefers RawAssistantContent → sends stale IDs → HTTP 400.
Fix: clear RawAssistantContent when dedup fires. Also merge consecutive
same-role messages (user↔user, assistant↔assistant) to fix role alternation
errors from session corruption.
2026-04-02 20:36:41 +07:00
viettranx 79cae648e4 fix(security): pairing expiry race, sender-ID validation, Slack senderID cleanup
- Add expires_at check to ApprovePairing SELECT (PG + SQLite) to close
  race between prune DELETE and code lookup
- Add isValidSenderID regex validation to handleRequest, handleRevoke,
  and handleBrowserPairingStatus (prevents log injection / bus poisoning)
- Add slog.Warn on decrypt fallback paths for downgrade detection
- Remove Slack compound senderID|displayName format; all channels now
  pass plain senderID with displayName in metadata
2026-04-02 20:29:44 +07:00
viettranx 7ba3a5115a fix(tools): hint model when shell commands target DB-backed memory files
Memory files (MEMORY.md, memory/*.md) are stored in PostgreSQL, not on
disk. When the model uses exec to run cat/ls/grep/find on memory paths,
short-circuit with a hint to use memory_search or memory_get instead.
Also append [Source: database, not filesystem] to read_file and
list_files results served from the memory interceptor.
2026-04-02 19:28:04 +07:00
viettranx 99720892a7 fix(storage): hide tenant roots from master storage API
Master tenant's base dir is the global data dir, which contains
the tenants/ cross-tenant isolation root. Without this fix, the
Storage page exposes tenant slugs, file names, and sizes.

- Extract topLevelPath() helper, remove dead code
- Add isHiddenPath() scoped to master tenant only
- Guard handleList, handleRead, handleSize with hidden path checks
- handleSize uses filepath.SkipDir to skip entire tenant subtree
- Add regression tests for list, read, size, subpath, and
  non-master tenant isolation
2026-04-02 19:05:46 +07:00
viettranx 484d434f6c fix(security): harden sandbox, auth, and shell deny patterns
Sandbox: add noexec/nosuid/nodev to tmpfs mounts, remove SETUID/SETGID/CHOWN
caps, add PidsLimit 256 default, keep no-new-privileges from base.

Auth: reject X-GoClaw-User-Id header spoofing in dev mode (no gateway token),
use full 32-byte HMAC for file tokens instead of truncated 16-byte.

Shell: add NFKC Unicode normalization + zero-width character stripping before
deny pattern matching, add 5 export-prefixed env var deny patterns, fix
exemption logic to check per-argument prefix instead of whole-command substring
(prevents bypass via comments while preserving skill store access).
2026-04-02 18:58:24 +07:00
viettranx 4c485d6fa1 fix(mcp): retry stdio transport initialization with exponential backoff
Heavy MCP servers (FastMCP with 80+ tools, OAuth servers) take 3-5s to
start their stdin read loop. Without retries, connectAndDiscover sends
the initialize request immediately after fork/exec, gets EOF, and
permanently fails with "transport closed".

Add a retry loop (4 attempts, 2s/4s/8s backoff) for stdio transports
only. SSE/HTTP transports fail immediately since connection-refused is
definitive. The retry respects context cancellation to avoid blocking
shutdown.

Closes #385
2026-04-02 18:43:41 +07:00
Huy DoanandViet Tran 1170a85eb4 Fix/brave search api key readonly (#648)
* fix(secure-cli): resolve ambiguous column in LookupByBinary JOIN query (#641)

LookupByBinary uses LEFT JOIN with secure_cli_user_credentials but
SELECT columns lacked table alias prefix, causing PostgreSQL error:
"column reference 'id' is ambiguous (SQLSTATE 42702)"

This silently broke ALL credentialed CLI exec — commands fell through
to regular shell exec without injected env vars.

Fix: use b.-prefixed column names for JOIN queries.
Also add diagnostic logging to lookupCredentialedBinary for future debugging.

* fix(agent): defer warning messages after parallel tool results (#644)

When parallel tool calls trigger loop detection warnings, the warning
messages (role="user") were inserted between tool result messages
(role="tool"). This breaks the Anthropic API when routed through
OpenAI-compatible proxies (e.g. LiteLLM): the proxy groups consecutive
tool messages into a single user message with tool_result blocks, but
an intervening user warning splits the group, causing orphaned
tool_results and HTTP 400 "tool_use ids without tool_result blocks".

Fix: accumulate warning messages during parallel result processing and
append them after all tool results, preserving the consecutive grouping.

Closes #642

* fix(web): allow editing Brave Search API key when masked

---------

Co-authored-by: Viet Tran <viettranx@gmail.com>
2026-04-02 18:39:30 +07:00
viettranx 7418cb62aa fix(agent): reduce system prompt size and fix team context injection (#613)
Prompt compression (Issue #613):
- Truncate skill descriptions to 200 runes in inline XML (matches mcpToolDescMaxLen)
- Lower skill inline token threshold from 5000 to 3000
- Compact tool descriptions (risk-audited: preserve behavioral hints)
- Compact boilerplate sections: media hint, safety, tool call style, spawn,
  self-evolve, skill creation, team workspace
- Fix token estimator to account for description truncation
- Restore safety anti-manipulation clauses dropped during compaction

Team context injection fix (found during prod audit):
- Add IsTeamLead field to LoopConfig/Loop, plumbed from resolver
- Gate team context (TEAM.md, workspace, members) on session type:
  leader inbound → team context; member-only inbound → spawn section;
  team dispatch → team context
- Filter TEAM.md from context files for member-only inbound chat
- Skip team member DB query when team context not needed
- Rename HasTeam → IsTeamContext for semantic clarity
- Add 8 table-driven tests for team context injection scenarios
2026-04-02 18:32:43 +07:00
viettranx cace4dcf31 fix(web): improve advanced settings dialog layout and width
Widen settings dialogs from sm:max-w-2xl (672px) to sm:max-w-3xl (768px)
to prevent cramped toggle groups. Move boolean field help text to a
separate line below the switch+label for cleaner readability.
2026-04-02 18:30:30 +07:00
viettranx 4e4a835795 fix(agent): defer warning messages after parallel tool results
When parallel tool calls trigger loop detection warnings, the warning
messages (role="user") were inserted between tool result messages
(role="tool"). This breaks the Anthropic API when routed through
OpenAI-compatible proxies (e.g. LiteLLM): the proxy groups consecutive
tool messages into a single user message with tool_result blocks, but
an intervening user warning splits the group, causing orphaned
tool_results and HTTP 400 "tool_use ids without tool_result blocks".

Fix: accumulate warning messages during parallel result processing and
append them after all tool results, preserving the consecutive grouping.

Closes #642
2026-04-02 16:43:53 +07:00
viettranx bfd65828a6 feat(web): add merge hint to CLI and MCP user credentials dialogs
Both dialogs now show an amber callout explaining that chat users
(Telegram, Discord, etc.) must be merged into a tenant user via
Contacts page before they can have per-user credentials.
i18n: en/vi/zh for both cli-credentials and mcp namespaces.
2026-04-02 15:18:06 +07:00
viettranx 5bad031908 fix(web): align CLI user credentials picker with MCP pattern
Replace raw Combobox + useUserPicker with UserPickerCombobox
component (source="tenant_user") to match MCP user credentials
dialog. Both systems use the same runtime user ID from context.
2026-04-02 15:15:36 +07:00
viettranx ddc5964b85 feat(web): replace user ID text input with Combobox user picker in CLI user credentials
Use existing useUserPicker hook + Combobox component to search
contacts + tenant_users instead of manual UUID entry.
Supports allowCustom for IDs not in the search results.
2026-04-02 15:10:30 +07:00
viettranx 79dce7e523 Merge branch 'hotfix/secure-cli-lookup-ambiguous-column' into dev 2026-04-02 15:02:43 +07:00
viettranx 9c92dead74 fix(web): force remount KG entity detail dialog on entity change
Add key={viewEntity?.id} to prevent stale relations/traversal data
when switching between entities without closing the dialog.
2026-04-02 15:01:20 +07:00
viettranx 19d8faf28f refactor(knowledge-graph): minor UI and handler adjustments 2026-04-02 14:58:03 +07:00
viettranx 3da84fcded fix(web): prevent tool card overflow during streaming
Add min-w-0 to ActiveRunZone flex content container.
Without it, long tool results (e.g. SQL output) push beyond viewport
creating horizontal scroll. MergedToolGroup already had this fix.
2026-04-02 14:57:58 +07:00
viettranx 10cd911dc7 feat(secure-cli): check-binary endpoint, agent select dropdown, fix ambiguous column
Backend:
- Add POST /v1/cli-credentials/check-binary to resolve binary via exec.LookPath
- Security: safeBinaryNameRe regex prevents filesystem probing
- Fix ambiguous column in LookupByBinary LEFT JOIN (secureCLISelectColsAliased)
- Add diagnostic logging to lookupCredentialedBinary

Frontend:
- Replace agent ID text input with Select dropdown (reuse useAgents hook)
- Add Check Binary button next to binary name (auto-fills resolved path)
- Add binary path hint explaining auto-detection from PATH
- Update i18n keys (en/vi/zh) for new UI elements
2026-04-02 14:57:50 +07:00
viettranx ec05c80e90 fix(secure-cli): resolve ambiguous column in LookupByBinary JOIN query
LookupByBinary uses LEFT JOIN with secure_cli_user_credentials but
SELECT columns lacked table alias prefix, causing PostgreSQL error:
"column reference 'id' is ambiguous (SQLSTATE 42702)"

This silently broke ALL credentialed CLI exec — commands fell through
to regular shell exec without injected env vars.

Fix: use b.-prefixed column names for JOIN queries.
Also add diagnostic logging to lookupCredentialedBinary for future debugging.
2026-04-02 14:56:49 +07:00
viettranx 0370cabdc9 chore: stabilize main branch with dev workflow + PR guidelines
- Set dev as default branch, protect main (owner-only merge)
- Add CI trigger for PRs targeting dev
- Add PR template with checklist and branch targeting guide
- Add CONTRIBUTING.md with branch strategy and review criteria
- Update README clone command to use -b main for stable
2026-04-02 12:36:30 +07:00
viettranx 62724780b8 feat(web): show richer context in traces list (agent, user, source, input preview)
Traces list Name column now displays agent display name, user label,
source type badge (Direct/Group/Cron/Team/Web), channel badge, and
truncated input preview — making it easy to identify which chat each
trace belongs to.
2026-04-02 12:15:09 +07:00
Huy Doanandviettranx 040ac31156 feat(web): add Brave Search API key to tools config UI (#627)
* feat(web): add Brave Search API key to tools config UI

Expose `web.brave.api_key` in the Web Search settings with password input,
strip masked values on save, and show the field only when Brave Search is
enabled. Add en/vi/zh strings for label, tooltip, placeholder, and managed key.

* refactor(web): extract isSecret to shared utility and fix mobile input font-size

DRY: move duplicated isSecret() from providers-section and tools-web-section
into lib/secret.ts. Add text-base md:text-sm to number inputs for iOS
Safari auto-zoom prevention.

---------

Co-authored-by: viettranx <viettranx@gmail.com>
2026-04-02 12:07:21 +07:00
viettranx 6baef0fb9c fix(telegram): add /reactions to bot menu commands
Register /reactions in DefaultMenuCommands() so it appears in
Telegram's command autocomplete menu after deploy.
2026-04-02 12:05:25 +07:00
viettranx a1323e0d1d feat(telegram): remap reaction emojis and add /reactions command
Remap status reaction emojis for clarity (tool: 🔥→✍, error: 😱→💔)
and reduce overlap between statuses. Add /reactions command to show
emoji legend table to users.
2026-04-02 12:02:12 +07:00
Huy Doan 173f1cea53 fix(cli-credentials): show existing env keys on edit and support merge/remove (#629)
fix(cli-credentials): show existing env keys on edit and support merge/remove

- Expose env_keys on secure CLI list/get and per-user credential list (values stay hidden)
- PUT merges env with stored secrets: empty value keeps existing, removed keys dropped
- Generic error messages to prevent env key enumeration
- Audit logging for user credential set/delete
- DRY: reuse envKeysFromDecryptedJSON helper
- Client-side env key name validation (en/vi/zh i18n)
2026-04-02 11:59:49 +07:00
viettranx 899c8eb0b4 fix(skills): fix dep detection false positives and all-or-nothing install
- Filter Python stdlib modules at scan time to prevent false positives
  when the runtime checker fails (e.g. pip:argparse, pip:sys)
- Install pip/npm packages one-by-one instead of batch so partial
  success is preserved when one package fails
- Persist missing deps to DB after install via StoreMissingDeps() so
  reload reflects actual state instead of stale data
- Use explicit master tenant context in handleInstallDeps for
  consistency with rescanAndUpdate()
2026-04-02 11:42:14 +07:00
viettranx ecf6463d98 fix(summon): preserve user's custom display_name during summon/regenerate
Previously, finishSummon() and RegenerateAgent() unconditionally overwrote
display_name with the LLM-extracted name from IDENTITY.md. Now if the user
already set a custom name, it is preserved and IDENTITY.md Name field is
synced to match — keeping UI label and agent self-identity consistent.
2026-04-02 11:04:56 +07:00
viettranx 9d74e39625 fix(telegram): stop auto-linking @mentions to t.me profile URLs
LLM @mentions are not necessarily Telegram usernames. Auto-wrapping
them in <a href="https://t.me/..."> caused unwanted profile cards.
Keep placeholder protection for italic conversion, restore as plain text.
2026-04-02 10:55:41 +07:00
viettranx 1a2d5789d3 fix(ui): show group names in permission scope dropdown
Replace raw scope strings (e.g. group:nta7-goclaw:-5101523...) with
human-readable group names by fetching delivery targets from
channel_contacts via heartbeat.targets API. Scope labels are also
resolved in the permissions list display.
2026-04-02 10:37:19 +07:00
viettranx 3e4d614aa1 feat(media): add Veo 3.1 Lite video generation with image-to-video support (#638)
- Switch default Gemini video model to veo-3.1-lite-generate-preview (50% cheaper)
- Add image_path tool param for image-to-video generation (Gemini Veo only)
- Add resolution and generate_audio as per-provider chain params in UI
- Support dual response formats (Veo 3.1 generatedVideos + Veo 3.0 generatedSamples)
- Gracefully skip image-to-video on providers that don't support it (MiniMax, chat)
- Split create_video into per-provider files (gemini, minimax, chat) for maintainability
2026-04-02 10:33:35 +07:00
viettranx 14c375e33b fix(media): update native provider API defaults and UI schema
- OpenAI image default: dall-e-3 → gpt-image-1.5 (dall-e-3 deprecated May 12)
- DashScope: add missing 4:3 and 3:4 aspect ratio mappings
- UI: remove stale MiniMax size/prompt_optimizer params (backend uses aspect_ratio since #630)
2026-04-02 09:53:01 +07:00
viettranx 83bcb16597 refactor(channels): extract health model and modularize UI components
Post-merge cleanup for #634 channel health diagnostics:

Backend:
- Extract health types, ClassifyChannelError, mergeChannelHealth,
  buildRemediation into internal/channels/health.go
- Fix case-true anti-pattern → default in Slack config
- Remove duplicate connection-refused case in ClassifyChannelError
- Remove unused _ bool param from BaseChannel.setHealth
- Fix snapshot.Enabled == false → !snapshot.Enabled

Web UI:
- Extract channel status utilities to channels-status-utils.ts
- Extract ChannelDiagnosticsCard from channel-detail-page.tsx
- Extract ChannelAttentionPanel from system-health-card.tsx

Desktop UI:
- Extract shared getChannelStatusDisplay() to utils/channel-status.ts
- Add explicit stopped state case for visual consistency with web UI
- Add missing vi/zh locale keys for new health status states
2026-04-02 09:45:41 +07:00
Tai Nguyen b5c4d1de2a fix bug can not create image with minimax provider (#630) 2026-04-02 09:35:21 +07:00
Kai (Tam Nhu) Tran 4cd7b0a8d4 feat: add actionable channel health diagnostics and remediation (#634)
* feat: add channel health diagnostics

* fix(channels): harden startup failure reporting

- sanitize operator-facing failure details instead of exposing raw upstream errors

- keep registered channel instances failed during reload/startup errors and clean up pre-registration failure entries

- stop Telegram warning states from reporting running=true after polling or startup failures

* feat(channels-ui): surface actionable health diagnostics

- expand channel and overview views with richer health summaries, remediation hints, and failure history

- refine the channel dashboard layout so diagnostics are easier to scan instead of reading a wall of text

- keep shared web and desktop channel types aligned with the new health payload

* fix(web): harden channel health diagnostics states

- treat enabled channels without backend status as checking instead of stopped\n- align fallback remediation and overview attention synthesis with channel reality\n- localize diagnostics copy and reject invalid channel detail tabs\n\nRefs #628\nRefs #633

* docs(pr-assets): add channel diagnostics visual review pack
2026-04-02 09:30:11 +07:00
viettranx abcb9614bc feat(providers): allow provider_type changes on update with SSRF re-validation
Remove blanket rejection of provider_type on update. Instead, when
provider_type changes, re-validate the existing api_base against the
new type to prevent SSRF via ACP→non-ACP type switch.

This enables provider type changes in onboarding/setup flows while
maintaining security: ACP providers skip URL validation, so switching
from ACP to another type now forces URL re-validation.
2026-04-02 08:49:54 +07:00
Kai (Tam Nhu) Tranandviettranx 9fd9e1f47b fix(providers): recover Codex text from responses completion events (#631)
* fix(providers): recover Codex text from responses completion events

* fix(providers): honor Codex phase-aware response assembly

* refactor(providers): extract Codex stream state to separate file

Split codexMessageStreamState and related types/methods from codex.go
(457 lines) into codex_stream_state.go to comply with 200-line file
size guideline. Fix redundant nil check in registerMessageItem. Add
clarifying comment on reconcileCompleted edge case.

---------

Co-authored-by: viettranx <viettranx@gmail.com>
2026-04-02 08:47:26 +07:00
Thieu Nguyen c84f4ac905 docs: sync API endpoint documentation with codebase (#632)
Add ~55 undocumented REST endpoints and ~30 undocumented WS methods.
Remove 14 stale entries (custom tools HTTP, sessions HTTP, delegations WS).
New sections: tenants, system-configs, edition, TTS, browser, zalo, export/import.
2026-04-02 08:24:08 +07:00
viettranx 3266a66299 feat(workspace): split sharing UI - separate Memory & KG from Workspace
Reorganize workspace sharing section to distinguish shared workspace
from memory/knowledge graph sharing controls.
2026-04-02 08:23:19 +07:00