-
Notifications
You must be signed in to change notification settings - Fork 95
Swap WUI daemon connection for REST API #355
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Swap WUI daemon connection for REST API #355
Conversation
Changed default HTTP port from 0 (disabled) to 7777 to support REST API migration. Added configuration documentation for HTTP server environment variables.
Replaced Tauri-based JSON-RPC client with HTTP client using HLD SDK. Added legacy type interfaces to maintain backward compatibility with existing UI code that expects snake_case properties. - Created HTTP client with connection retry and SSE support - Added configuration for daemon URL with environment variables - Updated type definitions to use SDK types with legacy mappings - Added SDK dependency and built it for local development The WUI remains a Tauri desktop app - only daemon communication changed.
…rmations - Add HTTPDaemonClient class with complete REST API implementation - Implement transform functions for Session, Approval, and Message types - Handle both camelCase (SDK) and snake_case (UI) property formats - Add connection retry logic with 3 attempts - Support SSE event subscriptions with automatic reconnection - Replace Tauri-based client with HTTP implementation 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Import SessionStatus, ApprovalStatus, and EventType as values (not type-only) - Add Legacy interfaces to maintain backward compatibility with snake_case UI - Map SDK types to legacy types for gradual migration - Add comprehensive TODO explaining future refactor plan - Fix SessionSnapshot to map to FileSnapshotInfo 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Replace unlisten with unsubscribe for event subscriptions - Fix SDK method signatures (health, listApprovals, getRecentPaths) - Update event structure access (event.type instead of event.event.type) - Fix approvals response handling (array directly, not object) - Update continueSession response property names - Add proper subscription cleanup in all hooks 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Remove references to non-existent ApprovalStatus.Resolved - Add null checks for date/time formatting functions - Fix model enum mapping (claude-3-5-sonnet-20241022 → sonnet) - Update event handlers to use correct event structure - Fix approvals response handling in Layout component - Remove non-existent bulk_archive_sessions property reference 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- EventType is exported as a const object in SDK, not an enum - Import as type-only since values are passed as string literals - Fixes "Indirectly exported binding name 'EventType' is not found" error 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- SessionStatus and ApprovalStatus are const objects in SDK, not enums - Import with aliases and re-export as const assignments - Export both the value and type for each - Fixes "Indirectly exported binding name is not found" errors 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Change tsconfig.json module format from commonjs to ES2020 - Fix "exports is not defined" error when SDK loads in browser - Revert namespace import workarounds now that SDK exports ESM - SDK now uses standard ES module syntax (export/import) This was the root cause of all the import/export binding errors. The SDK was built as CommonJS which doesn't work in browser environments. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add X-Client and X-Client-Version headers to the allowed CORS headers in the HTTP server to support client identification in REST API calls.
- Remove duplicate connection logic from Layout.tsx - Use centralized connection management from useDaemonConnection hook - Enable periodic health checks every 30 seconds - Single source of truth for daemon connection state - Clean up debug logging added during investigation This fixes the missing periodic health checks by properly utilizing the hook that was designed for connection management. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Major refactoring to eliminate duplicate SSE connections and improve performance: - Consolidated all SSE subscriptions to a single connection in Layout.tsx - Added activeSessionDetail to Zustand store to centralize session state - Removed duplicate SSE connections from useSession hook - Updated useConversation to read from and update the store - Fixed session loading to show skeleton UI properly - Added proper loading/error states in activeSessionDetail - Removed unnecessary useSession hook abstraction - Fixed daemon client method names (getConversation not getSessionMessages) This should significantly reduce browser connection usage and prevent the server lockup issues when navigating in/out of SessionDetail views. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Import SessionStatus in appStore.ts - Fix launchSession return type to use CreateSessionResponseData - Update useSessions to use correct response properties (sessionId/runId) - Fix parameter handling in http-client for both camelCase and snake_case - Convert getRecentPaths response from string[] to RecentPath[] - Add missing properties to minimal session object in SessionDetailPage - Fix undefined handling in useSessionActions Remaining errors are related to event IDs that might be undefined in SessionDetail components. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add checks for undefined event IDs before using them - Filter events with undefined IDs in navigation and approval hooks - Use non-null assertions after filtering - Add undefined checks in mouse event handlers - Prefix unused parameters with underscore All TypeScript errors are now resolved. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Caution
Changes requested ❌
Reviewed everything up to 70d7b54 in 2 minutes and 56 seconds. Click for details.
- Reviewed
3733
lines of code in35
files - Skipped
1
files when reviewing. - Skipped posting
7
draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. humanlayer-wui/src/components/internal/SessionDetail/eventToDisplayObject.tsx:79
- Draft comment:
JSON.parse is used directly assuming tool_input_json is non-null. It’s safer to check if tool_input_json exists before parsing to avoid runtime errors. - Reason this comment was not posted:
Comment was not on a location in the diff, so it can't be submitted as a review comment.
2. humanlayer-wui/src/components/internal/SessionDetail/eventToDisplayObject.tsx:355
- Draft comment:
The display logic function is very long; consider refactoring into smaller sub‐components for maintainability. - Reason this comment was not posted:
Comment was not on a location in the diff, so it can't be submitted as a review comment.
3. humanlayer-wui/src/hooks/useConversation.ts:35
- Draft comment:
Error count stops polling after 3 errors. Verify whether this behavior is desired or if a more robust retry mechanism is needed. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =30%
<= threshold50%
The comment is asking the PR author to verify if the behavior is desired, which violates the rule against asking for confirmation of intention. However, it does point out a potential issue with the error handling mechanism, which could be useful if rephrased to suggest a more robust retry mechanism directly.
4. humanlayer-wui/src/lib/daemon/http-client.ts:299
- Draft comment:
In subscribeToEvents, if connection fails the fallback polling strategy is initiated. Consider documenting the retry/fallback behavior to make future maintenance easier. - Reason this comment was not posted:
Comment did not seem useful. Confidence is useful =20%
<= threshold50%
The comment suggests documenting the retry/fallback behavior, which is a request for documentation rather than a code suggestion or a request for a test. It doesn't align with the rules as it doesn't provide a specific code suggestion or highlight a potential issue with the code itself.
5. humanlayer-wui/src/stores/appStore.ts:424
- Draft comment:
The clearNotificationsForSession action rebuilds a set filtering out IDs including the session ID. Consider whether matching substring is robust enough, or if a more structured notification identifier should be used. - Reason this comment was not posted:
Comment was not on a location in the diff, so it can't be submitted as a review comment.
6. humanlayer-wui/bun.lock:757
- Draft comment:
Typo detected: The dependency 'devlop' in the dependency list for 'hast-util-to-jsx-runtime' appears suspicious. Did you mean 'develop' or is this an intentional package name? - Reason this comment was not posted:
Comment was on unchanged code.
7. humanlayer-wui/bun.lock:893
- Draft comment:
Typographical error: It seems that "devlop" might be a misspelling. Did you mean "develop"? - Reason this comment was not posted:
Comment was on unchanged code.
Workflow ID: wflow_eIudZaQz0SVLxHxe
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
updateSessionStatus: (sessionId: string, status: string) => | ||
set(state => ({ | ||
sessions: state.sessions.map(session => | ||
session.id === sessionId ? { ...session, status: status as any } : session, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using the proper SessionStatus type instead of casting status as any in updateSessionStatus. This could improve type safety.
What problem(s) was I solving?
The WUI (Web UI) was communicating with the HLD daemon using a legacy Tauri-based JSON-RPC client, which limited development flexibility and made it harder to maintain consistency with other components that use the REST API. Additionally, the HTTP server was disabled by default (port 0), preventing REST API usage.
Key issues being addressed:
What user-facing changes did I ship?
Configuration Changes:
HUMANLAYER_DAEMON_HTTP_PORT
,HUMANLAYER_DAEMON_HTTP_HOST
).env.example
file documenting configuration optionsPerformance Improvements:
Developer Experience:
How I implemented it
1. HTTP Server Configuration (hld/)
config/config.go
hld/README.md
X-Client
,X-Client-Version
)2. SDK Integration (hld/sdk/typescript/)
CreateSessionResponseData
)initOverrides
in session message requests3. WUI Migration (humanlayer-wui/)
HTTPDaemonClient
class with complete REST API implementation4. State Management Refactoring
Layout.tsx
activeSessionDetail
to Zustand store for centralized session stateuseSession
hook5. Type Safety Improvements
How to verify it
make check test
passesManual Testing Steps:
hld start
and verify it runs on port 7777VITE_HUMANLAYER_DAEMON_URL
)Description for the changelog
feat(wui): migrate from JSON-RPC to REST API communication
Important
Replaces Tauri JSON-RPC client with REST API client, enabling HTTP server by default and improving performance and developer experience.
HTTPDaemonClient
inclient.ts
.config.go
.Layout.tsx
.SessionDetail
views.HTTPDaemonClient
class with complete REST API implementation inhttp-client.ts
.AppStore.ts
.activeSessionDetail
to store for centralized session state..env.example
for configuration documentation.README.md
for new configuration options.This description was created by
for 70d7b54. You can customize this summary. It will automatically update as commits are pushed.