mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-10-07 16:38:34 +08:00
eb7c983169e9c6bdb2c9541dbb1031225a42c8f8
7500
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
eb7c983169 |
feat: bump @openhands/extensions to include github-repo-monitor and slack-channel-monitor (#781)
Pins @openhands/extensions from 7b33f64 (May 19) to b8c1869 (May 23), which adds two new automation catalog entries: - github-repo-monitor: watches GitHub repos for @OpenHands mentions - slack-channel-monitor: watches Slack channels for @openhands mentions Updates the popularity-order unit test to reflect the new 7-entry catalog ranking (github-repo-monitor at rank 98 sits between github-pr-reviewer at 100 and slack-standup-digest at 94). Co-authored-by: openhands <openhands@all-hands.dev> |
||
|
|
45da5606d6 |
fix: bump agent-server SDK to 1.23.1 (#782)
Fixes two bugs in the upstream agent-server SDK v1.23.0 that caused 500 Internal Server Error on POST /api/conversations: 1. LLM registry duplicate usage_id: The condenser and main agent LLMs both used usage_id='default', causing ValueError on conversation creation. v1.23.1 checks for existing usage IDs before registering. 2. Validation error handler crash: The _validation_exception_handler tried to JSON-serialize raw ValueError objects from Pydantic validation contexts, turning 422 errors into 500s. v1.23.1 properly sanitizes validation errors before serializing. Co-authored-by: openhands <openhands@all-hands.dev> |
||
|
|
489070029d |
fix(ci): publish directly with --tag latest to avoid OIDC dist-tag failure (#778)
* fix(ci): publish directly with --tag latest to avoid OIDC dist-tag failure The previous workflow published with --tag alpha then ran a separate npm dist-tag add to set latest. The second call failed with E401 because OIDC trusted publishing tokens don't cover post-publish registry mutations like dist-tag. Simplify to a single npm publish --tag latest, which is all we need until the first stable release (#395). * docs(ci): note that named prerelease dist-tags are removed under current policy Add a comment block explaining that alpha/beta/rc dist-tags are intentionally not published while issue #395's 'everything is latest' policy is active, so consumers pinning to named prerelease tags are not silently broken without notice. Co-authored-by: openhands <openhands@all-hands.dev> * docs(ci): add OIDC root cause to publish comment per review Co-authored-by: openhands <openhands@all-hands.dev> --------- Co-authored-by: openhands <openhands@all-hands.dev> |
||
|
|
5d7f539303 |
fix(docker): ensure latest tag always points to latest stable release (#780)
Previously, the merge-manifests job unconditionally aliased main→latest
on every push to the main branch. This meant any commit to main after a
release would overwrite the `latest` multi-arch manifest with unreleased
main-branch code instead of the most recent stable tagged version.
The per-arch build already adds `latest-{arch}` tags exclusively for
stable (non-pre-release) version tags (e.g. v1.2.3), and the manifest
merge loop correctly creates the `latest` multi-arch manifest from
those arch-suffixed images. The extra main→latest alias was redundant
for tag pushes and incorrect for plain main pushes.
Remove the main→latest alias so `latest` is only produced by stable
version tag pushes, ensuring `docker pull …:latest` always gets the
highest stable release.
Co-authored-by: openhands <openhands@all-hands.dev>
|
||
|
|
43c10810da |
fix: switch @openhands/typescript-client from git dep to npm registry (#779)
* fix: switch @openhands/typescript-client from git dep to npm registry Replace the git+https dependency with the published npm package (v1.23.3). Git dependencies break `npm install -g` because npm clones the repo and runs the prepare script, but devDependencies like rimraf aren't available during global installs. Co-authored-by: openhands <openhands@all-hands.dev> * test: add guard against git dependencies in package.json Git dependencies break `npm install -g` because npm clones the repo and runs the prepare script without devDependencies. Add a test that fails if any dependency uses a git URL, with an allowlist for @openhands/extensions (not yet published to npm). Co-authored-by: openhands <openhands@all-hands.dev> * test: also catch bare owner/repo GitHub shorthand in git dep guard Co-authored-by: openhands <openhands@all-hands.dev> --------- Co-authored-by: openhands <openhands@all-hands.dev> |
||
|
|
cc63f48a07 |
refactor(acp): source ACP model lists from typescript-client (closes #740) (#775)
* refactor(acp): source model lists from typescript-client registry Replace the hand-mined CLAUDE_MODELS / CODEX_MODELS / GEMINI_MODELS lists (and the duplicated provider metadata) with the @openhands/typescript-client ACP registry, which mirrors the Python SDK source of truth (openhands.sdk.settings.acp_providers). acp-providers.ts becomes a thin adapter: it enriches each upstream record with Canvas-only UI fields (brand icon + onboarding description) and keeps the helper functions + public export surface unchanged, so no consumers change. - Bump the @openhands/typescript-client pin to the #187 merge commit (082d4d46), which adds available_models / default_model to the registry. - Delete the three hardcoded model lists; build ACP_PROVIDERS from getAcpProvider() + a small ACP_PROVIDER_UI map. - Incidentally corrects the Gemini default to auto-gemini-2.5 (the CLI's auto-router default), matching the merged SDK/client. Closes #740. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(acp): pin typescript-client to v1.23.2 tag (was SHA) Now that typescript-client v1.23.2 is tagged/released (includes #187's ACP registry, mirroring SDK #3389), pin to the tag instead of the raw #187 merge SHA. v1.23.2 tracks the SDK's v1.23.2 patch line. Resolves to the same commit as the prior SHA, so no resolved-content change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ci(acp): remove obsolete ACP providers sync check The acp-providers-sync workflow + scripts/check-acp-providers-sync.mjs existed to keep Canvas's hand-kept ACP registry mirror in sync with the SDK source (agent-canvas#587). That mirror is gone — acp-providers.ts now sources its model data from @openhands/typescript-client, which carries its own SDK-drift check (check-acp-drift.py). So this canvas-side check is redundant and was failing on the refactored ACP_PROVIDERS (no longer a literal array). - Delete .github/workflows/acp-providers-sync.yml + the script. - Drop the docs-version-sync test case that asserted the script's example. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Debug Agent <debug@example.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
3e0d915526 |
chore: bump version to 1.0.0-alpha.4 (#771)
Co-authored-by: openhands <openhands@all-hands.dev> |
||
|
|
89abe93a28 |
chore: bump automation version to 1.0.0a5 (#774)
Co-authored-by: openhands <openhands@all-hands.dev> |
||
|
|
3d724dd8fd |
feat(acp): versioned ACP model picker + per-conversation agent chip (#730)
* feat(acp): save concrete model defaults in canvas
* test(acp): verify provider models from subprocesses
* feat(acp): per-conversation agent chip + versioned Claude model picker
User-visible changes:
- Conversation cards now show a single inline chip `[brand mark] {model}`
on every conversation. ACP cards always render (identity info); OpenHands
native cards render whenever `agent.llm.model` is present. New
`AgentBrandIcon` covers Claude / Codex / Gemini brand marks with a
terminal-glyph fallback; the OpenHands logo is recolored via
`[&_path]:fill-current` so it inherits the muted-grey chip color
(the shipped SVG hardcodes `fill="white"`).
- Settings → Agent dropdown for Claude Code lists 10 versioned options
(Opus 4.7, 4.6, 4.6/1M, 4.5, 4.1; Sonnet 4.6, 4.6/1M, 4.5; Haiku 4.5;
opusplan). Default switched from `sonnet` to `claude-opus-4-7`.
Canonical IDs were verified against the bundled `claude` CLI binary's
model registry — the static SDK `.mjs` shims don't carry the full
registry. `[1m]` aliases used for 1M-context variants (no canonical
`claude-*-1m` IDs ship in the SDK).
- `ConversationCardFooter` chip resolves the ACP model string from
`current_model_name → current_model_id → agent.acp_model → agent.llm.model`
(the `"acp-managed"` sentinel is filtered out), so the chip works
whether or not the agent-server populates the SDK runtime fields.
- Removed dead `showLlmProfiles` plumbing on `ConversationCard` /
`CompactConversationRow` / `ConversationPanel` pass-throughs that
used to gate the OpenHands model line behind a metadata-menu toggle.
Chip is now always shown when a model exists.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(acp): adapter cleanup + drop unauthenticated model-check script
- Extract `resolveAcpDisplayModel(info)` from the triple-nested ternary
in `toAppConversation`. Same precedence chain (runtime name → runtime
id → configured model → llm.model minus sentinel), just expressed once
with a loop and named conditions.
- Name the `"acp-managed"` literal as `ACP_MANAGED_SENTINEL` (exported)
and the `"default" / "default (recommended)"` strings as
`ACP_DEFAULT_PLACEHOLDERS`. The sentinel was referenced from 7 places
across source and tests.
- Trim `DirectConversationInfo.agent.kind` JSDoc to 3 lines (was 7).
- Delete `scripts/check-acp-provider-models.mjs` and revert the CI step +
triggers in `.github/workflows/acp-providers-sync.yml`. The script
spawned each ACP wrapper unauthenticated and validated Canvas's lists
against the wrapper's fallback model set — which is only 3 models for
Claude Code (sonnet / sonnet[1m] / haiku) regardless of what the
wrapper actually accepts. The check flagged every legitimately-added
Opus entry as drift. Removing it; followup tracked in #740 for moving
the lists into `@openhands/typescript-client`.
- Remove `test:acp-models` npm script (only invoked the deleted file).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(acp): plug review-flagged gaps in model resolution + chip path
Five behavioral fixes + two refactors from review feedback on PR #730:
- F1: ``normalizeAgent`` and ``requireDirectConversationInfo`` were
dropping ``agent.acp_model``, ``current_model_id``, and
``current_model_name`` on the way in from the wire — so the chip
resolver only worked in unit tests (which build ``DirectConversationInfo``
in-process) and silently fell back to provider-name labels in production.
Normalizer now preserves all three.
- F2: ChatInputActions gated rendering ChatInputModel on
``isCloud || conversation?.agent_kind === "acp"``, so on a local home
screen with no active conversation it always picked SwitchProfileButton.
SwitchProfileButton then hid itself for ACP — net result: the home-ACP
model label never appeared. Added ``isHomeAcp`` derivation from
``settings.agent_settings.agent_kind`` so the chat input picks
ChatInputModel in that case too.
- F3: Switching the preset dropdown to Custom set ``isCustomAcpModel``
but left ``acpModel`` untouched, so a user moving Claude Code → Custom
+ typing a custom command could save ``acp_model: "claude-opus-4-7"``
on an unrelated wrapper. Now clears ``acpModel`` on Custom selection.
- F4: ``buildConfiguredAcpAgentSettings`` was stripping null / empty
``acp_model`` and not falling back to ``provider.default_model``, so
existing users with ``acp_model: null`` saw the new registered default
in Settings → Agent but their next conversation still started with the
agent-server's own default (UI/runtime mismatch). Conversation creation
now substitutes the provider default for empty values, matching what
the form displays.
- F5: ``isAcpDefaultPlaceholder`` was applied only to runtime fields, not
to the ``configured`` (``agent.acp_model``) or ``sdkLlm``
(``agent.llm.model``) fallback rungs of the precedence chain. Older
settings that persisted the literal ``"Default (recommended)"`` could
surface it on chips. Filter now applies uniformly.
- R1: All five surfaces (Settings form, conversation creation,
ChatInputModel, conversation adapter, chip) now route through one
helper, ``resolveEffectiveAcpModel({ runtimeName, runtimeId,
configured, sdkLlm, providerDefault })`` in ``acp-providers.ts``.
Placeholder + sentinel filtering live in one place. ``providerDefault``
is opt-in — chip omits it (don't lie about what's running), settings
/ creation / chat-input pass it (silently substitute the registry
default).
- R2: ``ACPProviderIcon`` no longer includes ``"openhands"`` — it's
ACP-only again. Reintroduced ``AgentBrandIconKind = "openhands" |
ACPProviderIcon`` for surfaces that can render either harness's mark.
Tests: ``acp-server-conversation-service.test.ts`` now exercises the wire
path with the new fields. ``agent-server-adapter.test.ts`` adds two cases
covering placeholder filtering on configured + sdkLlm rungs.
``agent-settings.test.tsx`` adds a Custom-preset-clears-default
regression. ``chat-input-model.test.tsx`` swaps the
"home + ACP renders nothing" assertion for "home + ACP shows the provider
default" — that's the new correct behavior.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(acp): translate new agent-settings keys + harmonize Gemini labels
Addresses the latest review pass:
- Translates ``SETTINGS$AGENT_CUSTOM_MODEL`` and ``SETTINGS$AGENT_MODEL_HINT``
into all 14 non-English locales (ja, zh-CN, zh-TW, ko-KR, no, it, pt, es,
ar, fr, tr, de, uk, ca). Both keys previously fell back to English text
on every non-English client, blocking the model dropdown's hint copy and
Custom-model label from being legible.
- Harmonizes the Gemini model labels with the Claude / Codex pattern —
raw IDs like ``gemini-3.1-pro-preview`` become ``Gemini 3.1 Pro
(preview)`` so the three providers read consistently in the dropdown.
- Adds provenance notes to ``CODEX_MODELS`` and ``GEMINI_MODELS`` mirroring
the Claude one — naming the upstream source the list was extracted from
and pointing at agent-canvas#740 (the long-term "move ACP model lists to
``@openhands/typescript-client``" plan).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(acp): address review — chip labels, dead toggle, icon de-dup, shared hook
- Chip shows the provider's picker label (e.g. "Claude Opus 4.7") instead of
the raw acp_model ID via new labelForAcpModel(); falls back to the raw ID
for custom overrides and the provider name when no model. (#1)
- Drop the stale version from the 1M labels (opus[1m]/sonnet[1m] →
"Claude Opus (1M)" / "Claude Sonnet (1M)") so the version-agnostic alias
and its label can't disagree. (#2)
- Remove the now no-op "Show LLM profiles" filter-menu row + its wiring
(chip is unconditional now; the preference no longer affects cards). (#4)
- Onboarding AgentOptionIcon delegates to AgentBrandIcon; delete the
duplicated brand-mark path constants and per-kind SVG markup. (#5)
- Name the OpenHands logo aspect ratio (3:2) so the chip and onboarding
tile render identically. (#7)
- Extract useAcpModelContext() shared by chat-input-actions and
chat-input-model to kill the duplicated isHomeAcp / destination-path /
label logic. (#6)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(acp): gate the agent chip behind the restored "LLM model" toggle
The chip was unconditional, which (a) silently flipped OpenHands cards from
main's model-hidden-by-default to always-shown and (b) left the panel's
"LLM model" toggle a no-op (then deleted). Restore one toggle that gates the
unified chip for BOTH ACP and OpenHands cards (default OFF), matching the
sibling "Repo and branch" metadata toggle.
- Footer: chip (ACP brand mark + model, OpenHands logo + model) now renders
only when showAgentChip is set.
- Restore showLlmProfiles plumbing: filter-menu row + ConversationPanel/
ConversationCard/CompactConversationRow pass-throughs (panel + filter-menu
are now byte-identical to main).
- ConversationCard.shouldRenderFooter gates ACP under the toggle too.
Net effect vs main for OpenHands: identical by default (hidden); when the
toggle is on, the only change is the OpenHands logo added next to the model
name. ACP identity chip becomes opt-in via the same toggle.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(acp): reconcile model on command edit, unify chip labels, dedupe provider lookup
Review follow-ups for the versioned ACP model picker + agent chip:
- agent-settings: editing the command textarea into a different provider
(or a custom command) now reconciles the model selector, so Save can no
longer silently persist e.g. claude-opus-4-7 against a Codex/custom
wrapper. The preset dropdown already did this; the textarea is the other
way a user switches providers. Also always show the custom-model input
when the dropdown is on "Custom" so a mismatched value is visible/editable
rather than hidden.
- chat input: surface the provider's human label (e.g. "Claude Opus 4.7")
for ACP conversations, matching the conversation-list chip, instead of the
raw acp_model id.
- relabel the conversation-panel "LLM model" toggle to "Agent / model" — it
now governs the ACP brand chip too.
- extract getAcpProvider() and replace the repeated ACP_PROVIDERS.find()
lookups across the adapter, settings, and the constants module.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(acp): stop filling the OpenHands logo's transparent hand paths
AgentBrandIcon recolored the OpenHands logo with a blanket
``[&_path]:fill-current``, which also overrode the two ``fill="transparent"``
hand shapes — turning the mark into a solid white blob on the onboarding tile
(and a filled blob on the conversation chip). The logo asset has 5
``fill="white"`` wordmark paths and 2 ``fill="transparent"`` hands; only the
former should inherit ``currentColor``.
Scope the override to ``[&_path:not([fill=transparent])]:fill-current`` so the
hands stay transparent (negative space), restoring the original two-tone logo.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Debug Agent <debug@example.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
c9616c1153 |
fix: pin openhands-sdk to same version as other SDK packages (#772)
Add openhands-sdk==${VERSION} to the --with list in both PyPI
resolution branches (specific version and default) of
buildAgentServerCommand so all four packages are pinned to the
same versions.agentServer:
openhands-agent-server, openhands-sdk, openhands-tools, openhands-workspace
Without this pin, openhands-sdk floated to the latest release on
PyPI (a transitive dep with no version bound in the published
openhands-agent-server metadata), causing non-reproducible builds
and version skew between the banner and defaults.json.
The local-path (editable) and git-ref branches are unaffected —
they already source all packages from the same checkout/ref.
Update the two affected unit-test cases to expect the new pinned
openhands-sdk entry in the args array.
Fixes #767
Co-authored-by: openhands <openhands@all-hands.dev>
|
||
|
|
f4d45e46fe |
fix(chat): enable git PR/push/pull on local without provider_tokens_set (#722)
Co-authored-by: Tim O'Farrell <tofarr@gmail.com> |
||
|
|
24a39212a8 |
fix(frontend): keep composer pinned at the bottom on narrow viewports (#765)
* fix: keep composer pinned at the bottom on narrow viewports * trigger build |
||
|
|
bf5b9e4390 | fix: stop calling /api/auth/workspace-session on cloud backends (#763) | ||
|
|
0d3783b422 |
fix(frontend): stop frontend bash probes on cloud runtimes (#761)
* fix: stop frontend bash probes on cloud runtimes * fix: failing tests |
||
|
|
0742445728 | fix: toast on run now success and failure (automation) (#759) | ||
|
|
2d494a4767 |
feat: execute git-info probe commands over bash-events WebSocket (#646)
Replace per-poll REST calls in useLocalGitInfo with a persistent WebSocket connection to /sockets/bash-events. Previously, useQuery's refetchInterval:10_000 caused AgentServerRuntimeService.executeCommand to fire individual HTTP requests on every tick (find + 2 git commands × up to 3 candidate dirs) to probe the workspace for git metadata. Changes: - websocket-url.ts: export buildBashWebSocketUrl() using the same host/pathPrefix extraction as the conversation-events URL builder - use-bash-command-runner.ts: new hook that maintains a persistent WS connection to /sockets/bash-events and exposes runCommand(command, cwd, timeout) → Promise. Commands queued during CONNECTING are flushed on open; all in-flight commands are rejected on close/error/unmount. - use-local-git-info.ts: swap AgentServerRuntimeService.executeCommand for useBashCommandRunner; keep refetchInterval:10_000 so branch changes (e.g. git checkout) are still reflected without a full refresh, but each probe now reuses the open socket rather than opening new HTTP connections. Co-authored-by: openhands <openhands@all-hands.dev> |
||
|
|
87b1079388 |
fix: persist home-page prompt draft to sessionStorage (#668)
* Persist home page prompt draft to sessionStorage Saves the chat input text on the 'Let's Start Building' home page to sessionStorage (debounced) so it survives navigation and failed conversation starts. - Restored when navigating away and back to the home page - Restored on page refresh within the same browser session - Cleared only on successful conversation creation (navigate away) - Discarded automatically when the browser tab is closed useDraftPersistence: when conversationId is undefined (home page context), save/restore/clear via sessionStorage[HOME_PROMPT_DRAFT_KEY] instead of the existing no-op path. Exports HOME_PROMPT_DRAFT_KEY constant. HomeChatLauncher: remove the sessionStorage key in onSuccess before navigating to the new conversation, so a fresh home page starts clean. Co-authored-by: openhands <openhands@all-hands.dev> * fix: flush home-page draft to sessionStorage on unmount The previous implementation debounced sessionStorage writes (500ms), which meant text typed and then quickly navigated away from — before the debounce fired — was never persisted. The unmount cleanup cancelled the pending timer, leaving sessionStorage with the stale value from the last full save, which was then incorrectly restored on the next visit. Fix: in the unmount cleanup, synchronously flush the current input text to sessionStorage when conversationId is undefined (home-page context). The debounce still handles the in-flight saves; the flush ensures nothing is lost when the component tears down with a pending timer. Co-authored-by: openhands <openhands@all-hands.dev> * fix: save home-page draft synchronously; use ref not DOM in flush Two bugs caused the wrong prompt to be restored after in-app navigation: 1. React 18 clears ref.current during the synchronous commit phase, before async useEffect cleanup functions run. The flush-on-unmount was reading chatInputRef.current — which is null at that point — so it never saved the updated text, leaving sessionStorage with the stale value. 2. The 500 ms debounce in saveDraft left a window where text typed and then navigated away from quickly would also not reach sessionStorage. Fix: - saveDraft (home-page path): write synchronously on every onInput event; no debounce needed for a sessionStorage write of a few hundred chars. Track the written text in lastHomeTextRef. - Restoration: seed lastHomeTextRef with the restored draft so an immediate navigate-away (without typing) still preserves it. - Unmount flush: read from lastHomeTextRef (always valid) instead of chatInputRef (null by cleanup time). Co-authored-by: openhands <openhands@all-hands.dev> * fix: ignore stale messageToSend for home-page draft restoration useAutoResize has an effect that writes `value.text` (sourced from the Zustand store's `messageToSend`) directly to the chat input element. After navigating away from /conversations and back, the store still holds the stale `messageToSend = { text: '' }` set during the previous visit. This caused a race with the sessionStorage draft restoration: 1. useDraftPersistence (effect B) restored the saved draft into the element 2. useAutoResize's value-update effect (E) then ran with the stale empty-string value and set element.textContent = '', erasing the draft 3. React 18 StrictMode double-invokes effects, so the second pass of the drawer-state effect (D) read the now-empty element and queued another setMessageToSend(''), keeping the text permanently gone A page refresh reset the store to messageToSend = null, which caused useAutoResize to skip its content update (value === undefined), making the draft visible – hence 'refresh works but navigation back doesn't'. Fix: on the home page (no conversationId) return null for messageToSend from useChatInputLogic, keeping value === undefined for useAutoResize and ensuring the content-update effect is never triggered there. Also guard the drawer-state effect so it only runs in conversation views. Co-authored-by: openhands <openhands@all-hands.dev> * fix: don't restore home-page draft on unmount if key was intentionally cleared The unmount flush in useDraftPersistence wrote lastHomeTextRef.current back to sessionStorage whenever the component tore down on the home page. This undid the explicit sessionStorage.removeItem call that HomeChatLauncher.onSuccess makes immediately before navigating to the new conversation, so the submitted prompt was still present when the user navigated back home. Fix: wrap the sessionStorage.setItem in the unmount cleanup with a check that the key already exists. saveDraft writes synchronously on every keystroke, so the key is always present when there is unsaved text. If the key is absent it was intentionally removed (successful conversation start), and the flush must not restore it. Co-authored-by: openhands <openhands@all-hands.dev> --------- Co-authored-by: openhands <openhands@all-hands.dev> |
||
|
|
4415e69083 |
fix: route cloud workspace-session through callCloudProxy to avoid CORS (#738)
Fixes issue #737: cloud conversation workspace-session call bypasses proxy, fails with CORS The useWorkspaceSession hook was making direct browser POST requests to cloud runtime sandboxes (*.prod-runtime.all-hands.dev) which don't allow CORS from localhost. This violates the rule documented in AGENTS.md that all browser → cloud backend calls must go through callCloudProxy(). Changes: - Add cloud/local branch in queryFn based on active backend kind - Cloud conversations route through callCloudProxy with session-api-key auth - Local conversations continue using RemoteWorkspace directly - Updated tests to cover both cloud and local paths Co-authored-by: openhands <openhands@all-hands.dev> Co-authored-by: hieptl <hieptl.developer@gmail.com> |
||
|
|
e49f6d721e |
feat(chat): attachment UX, upload-as-file, and home/cloud submit fixes (#712)
* feat(chat): merge tools menu into plus button with file upload footer Combine the chat tools dropdown with the + control and add an Add Files and Images action with a paperclip icon at the bottom. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(chat): support clipboard image paste on home and conversation inputs Read pasted screenshots from clipboard items, wire the home launcher through the shared attachment upload flow, and send first messages with attachments after creating a conversation. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(chat): per-pasted-image upload-as-file control on thumbnails Replace the global checkbox with a circular upload button on clipboard pasted images, track paste source in the store, and fix overlay stacking. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(chat): polish pasted-image upload toggle styling and tooltips Match the remove button size and corner inset, show a checkmark when active with hover feedback, and swap the tooltip to "Do not upload as file". Co-authored-by: Cursor <cursoragent@cursor.com> * fix(chat): add bottom padding below attachment thumbnails row Match the chat input container's top inset so pasted images and files are spaced evenly above and below the thumbnail strip. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(chat): use surface grey for upload-as-file toggle and nudge position Replace invalid primary tokens with oh-surface/oh-muted styling for both states and raise the button slightly from the thumbnail corner. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(home): defer attachment sends until cloud start task is ready Cloud conversation creation can return a provisional `task-{uuid}` URL while the sandbox provisions. Sending messages or uploading files against that id caused 422 UUID parsing errors on the home `/conversations` input. - Queue attachments in memory keyed by start-task id when provisioning - Flush uploads and the user message once `useTaskPolling` sees READY - Always include typed text in the start request, even with attachments - Add store and flush helper tests Paste/drag on the home input were already wired; this fixes starting a conversation with attachments (or text + attachments) on cloud backends. Co-authored-by: Cursor <cursoragent@cursor.com> * Revert "fix(home): defer attachment sends until cloud start task is ready" This reverts commit 9a443088ca5b14613c72b60459e26f1d8fb0f545. * Reapply "fix(home): defer attachment sends until cloud start task is ready" This reverts commit 7ba6a267cedaa67dbf08948ddcd00b9c5d6e269c. * fix(chat): upload attachments into the conversation workspace File uploads targeted read-only /workspace in Docker dev stacks and cloud task flush used raw i18next before app init. Resolve the conversation working_dir for upload paths and use the initialized openhands i18n instance when flushing deferred attachments. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(cloud): route home attachments through the runtime sandbox Cloud file uploads and the first message were hitting the bundled local agent-server and 404ing. Defer home attachments until the start task is ready, upload via the provisioned runtime URL, and send events through the cloud proxy. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(chat): send home attachments in a single first message Skip initial_message when starting with attachments and avoid enqueueing optimistic duplicates after the attachment send already persisted the message. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(cloud): show home submit as first message during task provisioning Enqueue optimistic pending messages on cloud start-task routes so the chat shows the user's message while the sandbox provisions, hide empty-state suggestions during provisioning, and reassign pending bubbles to the real conversation id when the task is ready. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(chat): suppress spurious older-messages errors on new conversations Skip auto-pagination when the initial history page is complete, on cloud start-task routes, or while provisioning, and stop surfacing an error banner when older events cannot be anchored. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(chat): hide history skeleton when pending message is visible Treat optimistic home-submit bubbles as loaded content so the feed skeleton does not flash over the user's first message on new conversations. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(cloud): stop empty-state suggestions flashing after home submit Keep pending bubbles linked across task-to-conversation redirect, reassign them before paint on the real route, and tighten suggestion gating so the Let's Start Building overlay does not flash during provisioning. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(chat): show upload-as-file toggle on all attached images Mark every attached image for the per-image upload control, not just clipboard pastes, so file picker and drag-and-drop previews match pasted screenshot behavior. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(chat): use file-plus icon for upload-as-file toggle Replace the generic upload glyph with Lucide FilePlus so the per-image control reads more clearly as "add this image as a workspace file." Co-authored-by: Cursor <cursoragent@cursor.com> * refactor: remove unrelated files --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: hieptl <hieptl.developer@gmail.com> |
||
|
|
1e37615222 | fix: align Skills search input styling with MCP page (#752) | ||
|
|
9c0aba4d50 |
fix(frontend): unify modal close button and title styling (#747)
* fix: unify modal close button and title styling * revert: white-icon modal styling and standardize on ModalCloseButton |
||
|
|
5550ee9239 | fix: disable view toggle when no automations exist (#749) | ||
|
|
9626fc92ab |
Customize extensions UI and polish automations experience (#739)
* fix(ui): move skills type filters into search row dropdown Put skill type filters in a dropdown beside full-width search and keep the result count below. Add SkillsTypeFilterDropdown and update tests to open the menu before selecting a filter option. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): full-width MCP toolbar with section filter Replace the half-width MCP search with a toolbar matching skills: flex search plus Installed/Library section filter. Remove the skills list count row for a cleaner toolbar layout. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(ui): unify skills and MCP extension cards with detail modal and add toggles Polish the Skills and MCP pages with shared card chrome, circle plus/check install toggles, and richer skill inspection. Skills open a detail modal with metadata pills and a traditional enable switch; MCP library and installed cards use the same toggle and white-outline hover treatment, with installed servers opening the editor on card click. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): drop hover ring glow from extension module cards Remove the white ring on hover/focus so skills and MCP tiles keep the border highlight without the outer glow. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): align installed MCP cards with marketplace module layout Match the library tile structure: transport under the title, command or URL on a bottom grey detail line, and the same min-height and spacing. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(ui): add enable/remove tooltips and hover X on circle toggles Show Enable on the plus state and swap the checkmark to an X on hover when selected, with a Remove tooltip, across skills and MCP add toggles. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): show catalog description on installed MCP server cards Restore the marketplace description text above the command detail line so installed tiles match the library card content layout. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): clamp installed MCP descriptions and grey the command line Limit catalog descriptions to two lines and style the command/URL metadata row with tertiary-alt so only that detail line reads as muted grey. Co-authored-by: Cursor <cursoragent@cursor.com> * Thicken remove X and add destructive hover on toggle. Use stroke-based x-mark at 14px to match checkmark weight, with a soft red background when hovering to remove. Co-authored-by: Cursor <cursoragent@cursor.com> * Use cool grey styling for Auto-discovery skill type badge. Replace yellow/gold agentskills pill colors with neutral cool-grey tones aligned to the design system. Co-authored-by: Cursor <cursoragent@cursor.com> * Add top-right close buttons to skill and MCP modals. Introduce a shared ModalCloseButton and wire it into the skill detail, MCP install, and custom server editor panels. Co-authored-by: Cursor <cursoragent@cursor.com> * Match MCP custom editor modal width to other modals. Use 520px panel width so the edit form aligns with the skill detail and install modals. Co-authored-by: Cursor <cursoragent@cursor.com> * Disable resizing on skill detail content textarea. Use resize-none on the readonly content field so the modal layout stays fixed. Co-authored-by: Cursor <cursoragent@cursor.com> * Move skill detail enable toggle below header row. Place the switch in a full-width settings bar so it no longer collides with the top-right close button. Co-authored-by: Cursor <cursoragent@cursor.com> * Add delete with confirmation to MCP custom editor. Show a destructive footer action in edit mode and reuse the shared confirmation modal before removing the server. Co-authored-by: Cursor <cursoragent@cursor.com> * Style MCP editor delete as secondary button with trash icon. Match the bordered secondary treatment used by Cancel while keeping a clear delete affordance via Trash2. Co-authored-by: Cursor <cursoragent@cursor.com> * Keep marketplace MCP cards in add-only toggle state. Library tiles always show the plus affordance since users may install multiple instances of the same server template. Co-authored-by: Cursor <cursoragent@cursor.com> * Use solid border on MCP installed empty states. Replace dashed outlines on the installed-servers empty and no-results panels with a standard border. Co-authored-by: Cursor <cursoragent@cursor.com> * Use shared Dropdown for MCP and skills filter controls. Replace bespoke filter menus with EnumFilterDropdown so toolbar filters match the site-wide combobox styling and behavior. Co-authored-by: Cursor <cursoragent@cursor.com> * Use tertiary-alt grey for MCP and skills secondary copy. Align card descriptions, modal hints, and empty-state text with the muted tone used for paths and subtitles elsewhere. Co-authored-by: Cursor <cursoragent@cursor.com> * Use tertiary-light for MCP and skills descriptive copy. Match card descriptions, modal body text, and empty states to the page header subtitle tone. Co-authored-by: Cursor <cursoragent@cursor.com> * Align MCP empty-state hint with tertiary-light copy tone. Co-authored-by: Cursor <cursoragent@cursor.com> * Make filter dropdown triggers hug their label width. Add fitContent mode to the shared Dropdown and use it for MCP/skills filters instead of a fixed 9rem trigger. Co-authored-by: Cursor <cursoragent@cursor.com> * Match filter dropdown trigger styling to toolbar search fields. Use rounded-lg, base-secondary background, and shared border/focus treatment; keep the active-filter highlight when not on All. Co-authored-by: Cursor <cursoragent@cursor.com> * Replace filter combobox with a simple right-aligned menu. Use a button-only toolbar filter with a menu anchored to the trigger's right edge and no type-to-search input. Co-authored-by: Cursor <cursoragent@cursor.com> * Add shared constants for the skills installation docs link. Centralize the OpenHands adding-skills guide URL and example /add-skill command so the skills UI can reference them without inline literals. Co-authored-by: Cursor <cursoragent@cursor.com> * Add an Add skill button and instructions modal on the skills page. Opens a fixed-header modal that explains using /add-skill in chat, highlights key paths with inline code chips, provides a copyable example command, and links to the OpenHands adding-skills documentation. Co-authored-by: Cursor <cursoragent@cursor.com> * Keep disabled skill cards at full opacity on the skills page. Remove the card-wide opacity-70 dimming so only the enable toggle reflects disabled state, matching clearer card readability when a skill is turned off. Co-authored-by: Cursor <cursoragent@cursor.com> * Add Use skill actions that open a new chat with a prefilled command. Share launch logic across the add-skill and skill detail modals, disable Use skill when a skill is off, and use the message-square-share icon for the primary action. Co-authored-by: Cursor <cursoragent@cursor.com> * Match recommended automation card hover styling to skills and MCP tiles. Reuse the shared extension module card surface and interactive hover classes so automation cards get the same border and background lift on hover. Co-authored-by: Cursor <cursoragent@cursor.com> * Use the same monochrome styling for all skill type badges. Trigger-based and Always active now share the cool grey Auto-discovery treatment instead of blue and green accents. Co-authored-by: Cursor <cursoragent@cursor.com> * Use container queries so Skills and MCP card grids collapse in narrow columns. Switch the shared grid from viewport md breakpoints to a 600px column-width container query so cards stay single-column when the extensions content area is tight, even on desktop layouts with the sidebar visible. Co-authored-by: Cursor <cursoragent@cursor.com> * Keep Skills extension pills on a single nowrap row with overflow. Harden pill chip styling and reuse SkillCardPillRow in the detail modal so badges never wrap to a second line in narrow cards or modals. Co-authored-by: Cursor <cursoragent@cursor.com> * Hide skill copy actions when the source is a scope label, not a path. Co-authored-by: Cursor <cursoragent@cursor.com> * Centralize extension module pill styling for reuse across Skills UI. Co-authored-by: Cursor <cursoragent@cursor.com> * Add MCP logo stack badge for multi-server automation card icons. Co-authored-by: Cursor <cursoragent@cursor.com> * Align recommended automation cards with Skills layout and shared pill row. Co-authored-by: Cursor <cursoragent@cursor.com> * Match automation list section headings to MCP Installed typography. Co-authored-by: Cursor <cursoragent@cursor.com> * Restore visible hover feedback on saved automation cards. Co-authored-by: Cursor <cursoragent@cursor.com> * Fix extension module card hover using valid tokens and a visible ring. Co-authored-by: Cursor <cursoragent@cursor.com> * Align saved automation cards with shared extension module surface chrome. Co-authored-by: Cursor <cursoragent@cursor.com> * Add a decorative plus badge to recommended automation cards. Co-authored-by: Cursor <cursoragent@cursor.com> * Limit extension card hover to a border highlight without glow or fill shift. Co-authored-by: Cursor <cursoragent@cursor.com> * Match saved automation card typography and pills to recommended cards. Co-authored-by: Cursor <cursoragent@cursor.com> * Make the automations search field span the full content width. Co-authored-by: Cursor <cursoragent@cursor.com> * Add an Add Automation header button that opens create instructions in a modal. Co-authored-by: Cursor <cursoragent@cursor.com> * Add hover and tooltip to recommended automation plus badges. Match the unselected CirclePlusCheckToggle affordance so decorative plus icons highlight on card hover and show a launch tooltip. Co-authored-by: Cursor <cursoragent@cursor.com> * Add a shared bordered empty-state panel class for extension pages. Centralize the rounded border/padding chrome used by MCP Installed and Automations list empty states. Co-authored-by: Cursor <cursoragent@cursor.com> * Redesign the automations empty state to match MCP installed styling. Use the shared bordered panel, drop the database icon, and add a secondary hint pointing users to the recommendations below. Co-authored-by: Cursor <cursoragent@cursor.com> * Align MCP installed empty state with shared panel and white title text. Reuse the shared empty-state container and render the primary line in white to match the automations empty state. Co-authored-by: Cursor <cursoragent@cursor.com> * Use the shared modal close button in Add Automation modal. Switch to ModalBackdrop and ModalCloseButton so the header and dismiss control match Skills and MCP modals. Co-authored-by: Cursor <cursoragent@cursor.com> * Add dispatchAutomation API for manual automation runs. Expose POST /api/automation/v1/{id}/dispatch for local and cloud backends with service-layer tests. Co-authored-by: Cursor <cursoragent@cursor.com> * Mock automation dispatch endpoint for manual runs. Return a pending run from POST /api/automation/v1/:id/dispatch in MSW with handler coverage. Co-authored-by: Cursor <cursoragent@cursor.com> * Add useDispatchAutomation mutation hook. Invalidate automation list, detail, and run history queries after a successful manual dispatch. Co-authored-by: Cursor <cursoragent@cursor.com> * Wire manual Run now dispatch through the automations list page. Pass dispatch handlers and pending state from the list route into automation groups and cards. Co-authored-by: Cursor <cursoragent@cursor.com> * Add i18n keys for automation card Run now and actions menu. Introduce AUTOMATIONS$RUN_NOW and AUTOMATIONS$ACTIONS_MENU for the saved automation card controls. Co-authored-by: Cursor <cursoragent@cursor.com> * Align automation kebab menu with shared context menu styling. Use ContextMenu rows, muted-to-foreground icon hover tokens, portal rendering to avoid overflow clipping, and drop the red delete styling. Co-authored-by: Cursor <cursoragent@cursor.com> * Replace saved automation card toggle with play Run now and menu actions. Add a play trigger, move Run now and View into the kebab menu with Lucide FileText, and keep turn on/off and delete under manage permissions. Co-authored-by: Cursor <cursoragent@cursor.com> * Show visible Run now label on saved automation cards. Co-authored-by: Cursor <cursoragent@cursor.com> * Tighten spacing between saved automation card title and description. Co-authored-by: Cursor <cursoragent@cursor.com> * Limit recommended automation plus badge hover to direct hover only. Co-authored-by: Cursor <cursoragent@cursor.com> * Set recommended automation plus badge tooltip to Add Automation. Co-authored-by: Cursor <cursoragent@cursor.com> * Add grid and list view toggle to the automations page. Let users switch saved automations between cards and table rows from a toggle beside search, with the choice persisted locally. Co-authored-by: Cursor <cursoragent@cursor.com> * Polish automations list view and replace view toggle with icon dropdown. Use secrets-style table surfaces and row hover, place pills beside the title, and swap the segmented control for a 36px icon menu without a caret. Co-authored-by: Cursor <cursoragent@cursor.com> * Show a checkmark on the selected automations view mode in the dropdown. Co-authored-by: Cursor <cursoragent@cursor.com> * Polish automations list layout, toolbar, and table row standards. Use two-column card grids, align search and view controls with skills/MCP toolbars, add shared compact table row sizing with lighter hover, and square icon actions with a Run now tooltip. Co-authored-by: Cursor <cursoragent@cursor.com> * Remove resting borders from extension module cards. Skills, MCP, and automation tiles now stay borderless until hover or keyboard focus, with shared CSS handling click focus without a stuck highlight. Co-authored-by: Cursor <cursoragent@cursor.com> * Match automation card Run now button height to the kebab menu. Use a shared h-8 text button class so grid card actions align with the 32px three-dot control. Co-authored-by: Cursor <cursoragent@cursor.com> * Tighten automation detail section header padding. Use symmetric py-3 on Configuration and Activity Log headers to match other modal section bars. Co-authored-by: Cursor <cursoragent@cursor.com> * Use theme tokens for skill type badge pill colors. Hardcoded cool-grey rgba values did not follow the active color theme; switch skill type badges to semantic text-secondary opacity tokens only. Co-authored-by: Cursor <cursoragent@cursor.com> * Fix skill toggle hover state and selected check styling. Use pointer hover instead of focus for the remove icon swap, show a white outline check when enabled, and let skill cards use a Disable tooltip. Co-authored-by: Cursor <cursoragent@cursor.com> * Show MCP stdio transport labels as STDIO in card headers. Co-authored-by: Cursor <cursoragent@cursor.com> * Remove Use skill action from the add skill modal. Co-authored-by: Cursor <cursoragent@cursor.com> * Redesign add-automation instructions and place chat caret after prefilled prompts. Replace the modal's plugin/conversation cards with inline guidance and a launch-in-chat action, and focus prefilled messages at the end for automation and skill flows. Co-authored-by: Cursor <cursoragent@cursor.com> * refactor: remove unrelated file * fix: failing tests --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: hieptl <hieptl.developer@gmail.com> |
||
|
|
56fcdc6b2e |
Remove direct HttpClient usage from agent-server APIs (#743)
* Show workspace version errors in canvas * Use current agent server version in mocks * Pin merged typescript client dependency * Use typescript client v1.23 release * Clarify typescript client release pinning guidance * Make snapshot baseline wait non-fatal on API errors * Remove direct HttpClient usage for agent server APIs * Validate LLM profile config before switching --------- Co-authored-by: neubig <398875+neubig@users.noreply.github.com> |
||
|
|
8cab54e0b1 |
Show agent-server version errors for workspaces (#742)
* Show workspace version errors in canvas * Use current agent server version in mocks * Pin merged typescript client dependency * Use typescript client v1.23 release * Clarify typescript client release pinning guidance --------- Co-authored-by: neubig <398875+neubig@users.noreply.github.com> |
||
|
|
27fe2469f2 |
UI polish: Neo theme, form system, sidebar, and conversation list (#733)
* feat(theme): add OpenHands-Neo theme with white primary buttons Introduce a neutral-based palette variant that overrides brand tokens at runtime, stop inlining primary colors on AgentServerUIRoot, and tie loaders to --oh-color-primary. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): standardize form controls to 36px rounded-lg styling Extract shared form-control class helpers and apply them across buttons, inputs, dropdowns, and settings fields; fix loading text contrast and backend retry button styling. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): indent switch helper text under labels Align description copy with toggle labels using shared pl-14 offset across agent, verification, and schema boolean fields. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): unify toggle switch and polish settings navigation Share an animated white-active toggle between settings and automations, align sidebar sub-nav rows to 36px, and match git settings helper copy to section subtitles. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): use font-medium for page and modal headings Standardize Typography H1–H3, modal titles, and route section headers on medium weight instead of semibold or bold. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): unify connected status green with sidebar indicator Route server and backend status dots through --oh-status-success so the conversation header and backend dropdown match the left nav. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): round toast corners to match button radius Use --oh-radius on all react-hot-toast surfaces and wire shared TOAST_OPTIONS into the root Toaster. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): unify combobox carets and polish error toasts Replace filled chevrons on dropdown triggers with a shared HeroUI-style caret, remove backend selector focus glow, and show CircleX on error toasts. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): remove hover delay on nav icons and dropdown carets Snap sidebar, settings, extensions, and dropdown hover colors instantly by excluding color from form-control transitions and using transition-none on nav rows. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): unify settings list styling and secrets header layout Extract shared list row/table classes for secrets and LLM profiles, use h-10 rows, and move the add-secret action to the top-right header. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): polish settings lists, profile menu, and error indicators Use h-12 list rows with subtler hover, align the LLM profile actions menu with shared context-menu styling, and unify error banner/toast icons on --oh-status-error. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): tighten conversation list row spacing to 2px Remove stacked link padding so folder rows and conversation cards use the same 2px vertical gap as grouped list sections. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): cap grouped conversation folders at five rows Show five conversations per workspace/repo folder with a grey More/Less toggle, keeping the active thread visible when it falls outside preview. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): polish conversation card metadata and launcher buttons Align card footer text with titles, drop the workspace folder icon, place branch beside repo name, match open launcher styling to secondary buttons, and darken grouped folder More/Less link color. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): size collapsed sidebar nav rows to 36px height Use a full-width 36px-tall hit target for collapsed rail icons instead of a fixed 40×40 square so nav rows match expanded row height. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): prevent sidebar logo flicker when collapsing Keep a single mounted logo in the header and briefly suppress the collapsed hover expand overlay so collapse does not flash the logo away. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): refine LLM profile editor header layout Hide the settings section title while adding or editing a profile, show a labeled Back control, and place the Add/Edit title below it using standard page heading styles. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): refine secrets add/edit form header layout Hide the list page title while adding or editing a secret, and show a Back control with Add/Edit a Secret headings using standard page styles. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): normalize button font weight to regular across the app Align buttons and button-like controls with the updated theme by defaulting shared form/BrandButton styles to font-normal and removing medium/semibold overrides from individual call sites. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): align error toast styling with chat error banner Top-align the error icon and use text-sm muted copy so toast notifications match the inline error message above the chat input. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): improve error toast icon alignment with message text Render the icon inside ErrorToastContent so it lines up with the message, center on single-line toasts, and top-align when the text wraps. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): shrink sidebar collapse toggle to match filter button Use a 28px hit target and 14px chevron so the collapse control matches the conversations filter icon button. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): polish conversation empty state, status menu, and logo Hide the no-conversations message until the first fetch completes, align the server status dropdown with other context menus, and remove the sidebar logo hover tooltip. Co-authored-by: Cursor <cursoragent@cursor.com> * fix: failing tests --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: hieptl <hieptl.developer@gmail.com> |
||
|
|
8df546950c |
Use SDK agent settings and model switch UI (#457)
* Use SDK agent settings for local conversations * chore: address PR review feedback (#457) Co-authored-by: openhands <openhands@all-hands.dev> * Show switch LLM tool results in model UI * chore: fix model switch formatting Co-authored-by: openhands <openhands@all-hands.dev> --------- Co-authored-by: openhands <openhands@all-hands.dev> |
||
|
|
2e3f8b64dd |
Add automation LLM profile controls (#536)
* Add automation LLM profile controls Co-authored-by: openhands <openhands@all-hands.dev> * Add automation LLM profile QA capture Co-authored-by: openhands <openhands@all-hands.dev> * Make automation LLM profile read-only Co-authored-by: openhands <openhands@all-hands.dev> * chore: Remove PR-only artifacts * test: cover automation manual dispatch Co-authored-by: openhands <openhands@all-hands.dev> * Display automation LLM profile names Co-authored-by: openhands <openhands@all-hands.dev> * Treat automation model as profile name Co-authored-by: openhands <openhands@all-hands.dev> * Use model field for automation profiles Co-authored-by: openhands <openhands@all-hands.dev> * Use model profile wording in automation test Co-authored-by: openhands <openhands@all-hands.dev> --------- Co-authored-by: openhands <openhands@all-hands.dev> Co-authored-by: allhands-bot <allhands-bot@users.noreply.github.com> |
||
|
|
b519dd0013 | fix: keep panel resize drag working over Files iframes (#729) | ||
|
|
b7edf55383 |
chat: add bottom padding to scroll area so typing indicator doesn't overlap last message (#735)
Refs OpenHands/agent-canvas#731 Co-authored-by: openhands <openhands@all-hands.dev> |
||
|
|
57f01fb512 |
feat(ui): modal polish — skills, hooks, tools, metrics, and conversation menu (#721)
* feat(skills): redesign available skills modal layout and grouping Polish the conversation skills modal with scoped sections, clearer header controls, monochrome pills, and consistent spacing while runtime or data loads. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(skills): align modal section labels with API terminology Rename Personal/Built-in section headers to User skills and Public skills so the Available Skills modal matches load_user/load_public naming. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(ui): align hooks/tools modals and polish conversation menu share row Match Available Hooks and Agent Tools modals to the skills modal patterns, refresh context menu icons, and make public sharing toggle instantly with a compact monochrome control plus copy/link actions. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(ui): polish system message modal tabs and content layout Use theme foreground tokens for the active tab label and underline, grey stroke for the tab baseline, and remove the redundant bordered inset around system message text. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(ui): use Lucide ExternalLink in conversation share dropdown Replace the custom SVG open-in-new-tab icon with Lucide's ExternalLink for consistency with other menu icons. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): round corners on public share menu row Match the hover background radius of other context menu items. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): align public share toggle thumb inset when on Nudge the on-state thumb 1px left so the right edge padding matches the off-state inset. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(ui): polish conversation metrics modal layout and labels Add a close button, surface-raised content container, white context-window progress fill, and simplify Input/Output/Total label copy. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): polish hooks modal layout and pluralize hook count labels Limit dark inset styling to command blocks, add expanded-section padding and matcher dividers, use i18next _one/_other for hook counts, and route the hooks query through the conversation service without dev mock data. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): align manage backends modal with other modal polish Use BaseModalTitle, a header close button, icon-only row actions, and a rounded raised list container so the modal matches hooks/skills/metrics. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): polish backend and MCP modals for layout, titles, and close controls Standardize modal titles on BaseModalTitle and text-content-2, add header close buttons to MCP install/custom flows, and refine manage/add-backend spacing, version pills, theme tokens, and advanced-section layout. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): use upright placeholder text across inputs and dropdowns Remove placeholder:italic from shared SettingsInput, dropdown comboboxes, and one-off form fields so placeholder hints match normal body type. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): standardize modal widths on sm/md/lg/xl scale Introduce shared modal width tokens in modal-body.tsx: - sm 384px — confirmations and simple pickers (ModalBody default) - md 520px — single-column forms - lg 640px — scrollable lists and multi-step wizards - xl 720px — two-column or sidebar + main layouts Export modalWidthClassName(), MODAL_WIDTH_CLASS, and MODAL_MAX_WIDTH_VIEWPORT (max-w-[90vw]) for bespoke modal shells. Migrations: - ModalBody: small/medium → sm/lg (700px medium became 640px lg) - MCP custom editor: 680 → md; MCP install already md - Plugin launch, API key modals, settings API modal, edit backend: → md - Manage workspaces, onboarding: 560 → lg; manage backends: lg (unchanged) - Add backend, folder browser: xl (720) with viewport max-width - Skills, hooks, system message: width="lg" Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): align backend and open-repository modal headers - Add top-right close control to edit-backend and open-repository modals - Drop fork icon from open-repository headers; title + X matches other modals - Balance add-backend two-column spacing (gap-6, remove stacked pl/pr/px padding) Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): add close control to open workspace dialog header Match other sm modals: title on the left, X on the right, no folder icon. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: hieptl <hieptl.developer@gmail.com> |
||
|
|
04ecb58e70 |
feat(skills): redesign available skills modal layout and grouping (#720)
* feat(skills): redesign available skills modal layout and grouping Polish the conversation skills modal with scoped sections, clearer header controls, monochrome pills, and consistent spacing while runtime or data loads. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(skills): align modal section labels with API terminology Rename Personal/Built-in section headers to User skills and Public skills so the Available Skills modal matches load_user/load_public naming. Co-authored-by: Cursor <cursoragent@cursor.com> * refactor: translation.json --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: hieptl <hieptl.developer@gmail.com> |
||
|
|
b027b86213 |
feat(ui): restyle chat error banner and add connection retry (#726)
* feat(ui): restyle chat error banner and add connection retry Replace red feed error styling with grey theme tokens, show a Retry action for server disconnects, and update the copy to "Unable to connect to server". Co-authored-by: Cursor <cursoragent@cursor.com> * fix(ui): top-align error banner actions for multi-line messages Detect wrapped message content so the close and retry controls stay pinned to the top-right instead of vertically centering. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: hieptl <hieptl.developer@gmail.com> |
||
|
|
2209f49af8 |
fix translations: add missing placeholders to zh-CN, zh-TW, ko-KR, tr (#700)
Fixed placeholder mismatches where dynamic variables were missing: - EXPLORER$UPLOAD_SUCCESS_MESSAGE: zh-CN, zh-TW, ko-KR - EXPLORER$UPLOAD_PARTIAL_SUCCESS_MESSAGE: zh-CN, zh-TW, ko-KR - EXPLORER$VSCODE_SWITCHING_ERROR_MESSAGE: zh-CN, zh-TW, ko-KR - LANDING$CHANGE_PROMPT: tr - DOWNLOAD$FOUND_FILES: tr - DOWNLOAD$FILES_PROGRESS: tr Co-authored-by: openhands <openhands@all-hands.dev> |
||
|
|
60bc93f0e9 |
Add backend management specs and @spec annotations (#727)
* Add backend management specs and @spec annotations - Curate specs/backend-management.md with 4 behavioral specs (BM-001–BM-004) - Add @spec comments to source and test files for traceability - Add spec file convention note to AGENTS.md Co-authored-by: openhands <openhands@all-hands.dev> * Remove duplicate BM-002 test (non-conversation redirect) The 'stays on settings' case was covered by two tests; keep the one with the clearer assertion and drop the redundant copy. Co-authored-by: openhands <openhands@all-hands.dev> * Parameterize BM-002 tests with it.each Collapse 3 identical-structure redirect tests into a single parameterized it.each covering conversation detail, automation detail, and non-ID routes. Co-authored-by: openhands <openhands@all-hands.dev> * Document @spec tagging convention in AGENTS.md Co-authored-by: openhands <openhands@all-hands.dev> --------- Co-authored-by: openhands <openhands@all-hands.dev> |
||
|
|
dcdef5832e |
feat(automations): add Download Tarball option to automation kebab menu (#725)
* feat(automations): add Download Tarball option to automation kebab menu
Add a 'Download tarball' menu item to the automation dropdown in both
the list card (AutomationCard) and the detail page header (DetailHeader).
The item appears after 'Turn On/Off' and before 'Delete', and triggers a
browser download via GET /api/automation/v1/{id}/tarball.
- Add download.svg icon (Heroicons outline style)
- Add AUTOMATIONS$DOWNLOAD_TARBALL i18n key with translations for all
15 supported locales
- Wire menu item to the tarball endpoint using a programmatic anchor click
Ported from OpenHands/automation feat/tarball-download-endpoint branch.
Depends on the new GET /{id}/tarball endpoint added in that PR.
Co-authored-by: openhands <openhands@all-hands.dev>
* fix(automations): rename tarball label to 'Tarball' and fix auth on download
- Shorten menu item label from 'Download tarball' to 'Tarball' to prevent overflow
- Replace bare anchor-click download (which opened an unauthed browser request)
with AutomationService.downloadTarball(), which fetches via the authenticated
axios client (Bearer token for local, cloud proxy for cloud backends) and
triggers the download from a blob URL
Co-authored-by: openhands <openhands@all-hands.dev>
---------
Co-authored-by: openhands <openhands@all-hands.dev>
|
||
|
|
e6d12e3fff |
fix(BM-001): auto-switch active backend on addBackend (#714)
* spec(BM-001): add spec + failing tests for auto-switch on connect Adding a backend should automatically switch the active selection to it. Currently addBackend registers the entry but leaves the user on the previous backend, forcing a manual switch. - specs/backend-management.md: BM-001 definition - Two new test cases (cloud + local) that assert the active backend changes after addBackend — both fail against the current implementation. Co-authored-by: openhands <openhands@all-hands.dev> * fix(BM-001): auto-switch active backend on addBackend addBackend now calls setActiveSelection after registering the new entry, so the user lands on the backend they just connected — whether via the manual host+key form or the cloud OAuth device-flow login. - src/contexts/active-backend-context.tsx: one-line fix in addBackend - Updated add-backend-modal test to assert the new active selection - Updated backend-selector tests that used addBackend purely as setup to reset active to the default local backend afterward Co-authored-by: openhands <openhands@all-hands.dev> * chore: remove noisy @spec markers from test setup comments Keep @spec BM-001 only where it marks the implementation or directly asserts the spec behavior. Setup-only adjustments (resetting active backend after addBackend) are incidental — plain comments suffice. Co-authored-by: openhands <openhands@all-hands.dev> * chore: consolidate @spec BM-001 to one test + one implementation site The spec marker belongs in exactly two places: the line that implements the behavior and the single test that verifies it. Removed the redundant local-backend variant (same code path as cloud) and dropped @spec labels from the modal test (its assertion stays, just without the tag). Co-authored-by: openhands <openhands@all-hands.dev> * refactor: remove setActive workarounds from backend-selector tests Instead of manually resetting active state after addBackend, tests now work with the auto-switch naturally: - Local backend tests: click the seeded default 'Local' (which is no longer active after auto-switch) to trigger the switch. - Cloud org tests: add a local backend after the cloud one so the last auto-switch lands on local, leaving cloud backends unselected and their org rows visible in the dropdown. No ctx.setActive(DEFAULT_LOCAL_BACKEND_ID) calls remain. Co-authored-by: openhands <openhands@all-hands.dev> * refactor: extract shared seed constants in backend-selector tests SEED_LOCAL_1 and SEED_CLOUD_PRODUCTION replace 12+4 identical inline config objects. The two remaining inline blocks have different apiKey values and correctly stay as-is. Co-authored-by: openhands <openhands@all-hands.dev> --------- Co-authored-by: openhands <openhands@all-hands.dev> |
||
|
|
5a64e0b3c3 |
docs: DefenseClaw security governance integration guide (#719)
* docs: add DefenseClaw security governance integration guide Explains how to integrate DefenseClaw (cisco-ai-defense/defenseclaw) with Agent Canvas and the OpenHands Agent Server without any code-level changes: - Load the DefenseClaw CodeGuard skill for secure-by-default code generation - Route LLM traffic through the DefenseClaw guardrail proxy (localhost:4000) - Pre-install skill scanning via the defenseclaw CLI - Post-generation workspace scanning with CodeGuard - Audit/observability via TUI, OTLP, Splunk, and webhooks Also documents six future code-level extension points (SecurityAnalyzer hook, skill install pipeline gate, hooks integration, UI dashboard, audit bridge, and registry alignment). Co-authored-by: openhands <openhands@all-hands.dev> * docs: replace ASCII diagrams with Mermaid in DefenseClaw integration guide Co-authored-by: openhands <openhands@all-hands.dev> * docs: rename integrating-defenseclaw.md to DefenseClaw.md Co-authored-by: openhands <openhands@all-hands.dev> * docs: simplify Mermaid diagram node labels Co-authored-by: openhands <openhands@all-hands.dev> --------- Co-authored-by: openhands <openhands@all-hands.dev> |
||
|
|
c61402e75b | fix: make Skills page responsive on mobile and tablet widths (#710) | ||
|
|
1df24af56a | fix: drop low-contrast placeholders from LLM provider/model dropdowns (#706) | ||
|
|
1c5be9f906 |
chore: change default model to MiniMax-M2.7 (#697)
* chore: change default model to MiniMax-M2.7 - Update DEFAULT_SETTINGS.llm_model to openhands/minimax-m2.7 - Update agent_settings.llm.model to openhands/minimax-m2.7 Co-authored-by: openhands <openhands@all-hands.dev> * fix: update test assertion and mock for new default model Co-authored-by: openhands <openhands@all-hands.dev> --------- Co-authored-by: openhands <openhands@all-hands.dev> |
||
|
|
0f52021e51 | docs: add No Magic Strings rule to AGENTS.md (#704) | ||
|
|
196d44f260 | chore: localize hardcoded strings in BtwMessages (#702) | ||
|
|
06c418cc8f |
fix(settings): filter Autocomplete items when typing in settingsdropdown (#683)
* fix(settings): filter Autocomplete items when typing in settingsdropdowninput * fix(settings): use defaultItems so Autocomplete filters while typing --------- Co-authored-by: Vasco Schiavo <115561717+VascoSch92@users.noreply.github.com> |
||
|
|
8640666999 | fix: open ellipsis menu by ignoring trigger in click-outside (#696) | ||
|
|
b3d5a61fe4 |
feat(frontend): persist local workspaces on the agent-server (#653)
* feat: persist local workspaces on the agent-server * refactor: update the code based on feedback * fix: lint |
||
|
|
e54b04cf38 | chore: refresh stale 1.22.1 doc examples after agent-server bump to 1.23.0 (#694) | ||
|
|
eee7fe1b7a | feat: use async conversations and interrupt endpoint for local mode (#670) | ||
|
|
22f1783ca9 |
ci(deps): bump the actions group across 1 directory with 2 updates (#590)
Bumps the actions group with 2 updates in the / directory: [actions/upload-artifact](https://github.com/actions/upload-artifact) and [actions/download-artifact](https://github.com/actions/download-artifact). Updates `actions/upload-artifact` from 4 to 7 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v4...v7) Updates `actions/download-artifact` from 4 to 8 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v4...v8) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: '8' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: actions/upload-artifact dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Engel Nyst <engel.nyst@gmail.com> |
||
|
|
eb9a01ed94 | fix: align agent settings save button label with other settings pages (#691) |