feat: add AskUserQuestion tool, migrate frontend to WebSocket #87

Merged
ph merged 3 commits from feature/ask-user-question into master 2026-06-15 10:08:26 +00:00
Owner

Summary

Adds a new AskUserQuestion tool that lets the model ask users structured questions and wait for answers. Also migrates frontend communication from SSE + HTTP POST to pure WebSocket.

What changed

AskUserQuestion tool:

  • Model can ask 1-8 questions (single-select, multi-select, text input)
  • 'Custom' option auto-appended to all selection questions as fallback
  • Blocks agent until user answers (5min timeout)

WebSocket migration:

  • Frontend now uses a single persistent WS connection for events + commands
  • approval store sends via WS instead of HTTP POST
  • New ws.ts connection manager with auto-reconnect

Files

Backend: internal/question/, internal/tools/ask_user_question.go, internal/api/handler.go, internal/daemon/pool.go, internal/types/events.go, internal/agent/system.go, internal/session/session.go

Frontend: web/src/lib/ws.ts, web/src/runtime/stream.ts, web/src/store/approval.ts, web/src/store/question.ts, web/src/components/QuestionDialog.tsx, web/src/lib/types.ts

Testing

  • Backend: 17 new tests covering resolver, handler validation, timeout, cancel
  • All existing tests pass
## Summary Adds a new `AskUserQuestion` tool that lets the model ask users structured questions and wait for answers. Also migrates frontend communication from SSE + HTTP POST to pure WebSocket. ### What changed **AskUserQuestion tool:** - Model can ask 1-8 questions (single-select, multi-select, text input) - 'Custom' option auto-appended to all selection questions as fallback - Blocks agent until user answers (5min timeout) **WebSocket migration:** - Frontend now uses a single persistent WS connection for events + commands - `approval` store sends via WS instead of HTTP POST - New `ws.ts` connection manager with auto-reconnect ### Files Backend: `internal/question/`, `internal/tools/ask_user_question.go`, `internal/api/handler.go`, `internal/daemon/pool.go`, `internal/types/events.go`, `internal/agent/system.go`, `internal/session/session.go` Frontend: `web/src/lib/ws.ts`, `web/src/runtime/stream.ts`, `web/src/store/approval.ts`, `web/src/store/question.ts`, `web/src/components/QuestionDialog.tsx`, `web/src/lib/types.ts` ### Testing - Backend: 17 new tests covering resolver, handler validation, timeout, cancel - All existing tests pass
Adds a new tool that lets the model ask users structured questions
(single-select, multi-select, text input) and wait for answers before
continuing. Frontend communication switches from SSE + HTTP POST to
pure WebSocket (approval now uses WS too).

Backend:
- internal/question/ — QuestionResolver with submit/resolve pattern
- internal/tools/ask_user_question.go — tool handler with validation
  and auto-append of 'Custom' option
- internal/types/events.go — new ask_user_question event type
- internal/api/handler.go — WS approve/question_response actions
- internal/daemon/pool.go — inject EventSink into context
- internal/agent/system.go — usage guidelines in system prompt

Frontend:
- web/src/lib/ws.ts — WebSocket connection manager
- web/src/runtime/stream.ts — SSE replaced with WS event stream
- web/src/store/approval.ts — HTTP POST replaced with WS send
- web/src/store/question.ts — question event handling
- web/src/components/QuestionDialog.tsx — question form component
Replaces the mixed SSE+HTTP approach with a pure WebSocket protocol:
- Request-response: every wsMessage has action + request_id + body,
  server replies {ok, data} or {ok, error} paired by request_id
- WSBridge: single class managing connection + request() / fire() /
  event$, exposed via BridgeProvider + useBridge() React Context
- api/client.ts: useAPI() hook returns typed request functions that
  use WSBridge.request() underneath — components never touch WS raw
- Removed all HTTP fetch calls and the entire web/src/api/ directory
  (agent.ts, sessions.ts, fs.ts, config.ts, traces.ts, background.ts,
  health.ts, client.ts)
- Runtime layer (stream.ts, approvalStore, questionStore, ChatStore)
  receives bridge instance via dependency injection
ph merged commit a8550c321e into master 2026-06-15 10:08:26 +00:00
ph deleted branch feature/ask-user-question 2026-06-15 10:08:26 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ph/agentic!87
No description provided.