Commit Graph

2 Commits

Author SHA1 Message Date
倪程伟
6bbb6489f4 feat(webchat): expose phase / tool_start / tool_end / plan as SSE events
Previously WebChatController.chatStream silently dropped every agent
lifecycle event except _usage_final (and content_delta / thinking_delta
derived from delta.payload). Visitors sat with nothing between the
meta event and the first content chunk — typically 3–10s when the
agent plans / recalls memory / runs tools, longer when the agent
chained multiple tool calls. The JWT chat path (ChatController) had
this wiring; webchat did not.

Curated 4-event subset (per design review):
- phase        — high-level phase transition (planning / generating /
                 summarizing / ...). SDK shows a "AI is thinking..."
                 typing indicator before the first token.
- tool_start   — agent invoked a tool. SDK shows a localized badge
                 ("Searching...", "Reading file.pdf", ...).
- tool_end     — tool completed. SDK clears the badge.
- plan         — Plan-Execute agents expose their step list. SDK can
                 render a checklist.

Deliberately NOT forwarded (internal noise / leak risk):
- _usage_final, _routing_decision — consumed internally
- finish_reason                  — implicit in `done`
- feedback_event                 — visitor can't retry/regenerate anyway
- perf_summary, iteration_*      — internal metrics
- plan_step_started/completed    — too granular; the plan event covers
                                   the visitor's needs

Critical safety constraint: tool_start / tool_end carry ONLY the tool
name. Tool arguments and results are dropped — agent tool calls can
contain PII (file paths, user queries, credentials), and relaying
those to a 3rd-party website frontend is a data leak. The SDK maps
tool name → localized label via its own lookup.

Backward compat: existing clients ignore unknown event types per the
SSE spec, so adding these is non-breaking.

Tests: 5 new cases in WebChatStreamE2ETest covering each event type
+ a regression case asserting internal events are silently dropped.
85/85 webchat tests green.

Docs: docs/zh/webchat.md gains a "实时进度事件" subsection.

Stack: feat/webchat-attachment-e2e → feat/webchat-stream-phase-events
Follow-up to epic #355.
2026-06-18 06:33:17 +08:00
倪程伟
59713a7215 test(webchat): HTTP e2e coverage for POST /stream (epic #355 PR 5)
Adds WebChatStreamE2ETest — first test in the suite to boot a real
servlet container (RANDOM_PORT) and exercise /stream over actual HTTP,
parsing the SSE wire format that any third-party SDK would see.

AgentService is swapped with a Mockito @MockBean so chatStructuredStream
returns canned StreamDeltas — fast, deterministic, no real LLM.

Coverage:
- happy path: meta → content_delta* → done, assistant reply persisted
- multi-chunk reply with thinking_delta + _usage_final event
  (verifies persisted prompt_tokens / completion_tokens / runtime_model)
- bad API key → SSE error event "Invalid API Key"
- blank message → SSE error event "Message is required"
- channel with no bound agent → SSE error event "No agent configured"
- explicit sessionId → meta echoes it + seeds conversation namespace
- invalid visitorId charset → SSE error event

7 tests, ~5s. Mid-stream stop is covered by WebChatStopStreamTest at
the controller level; attachment ingestion is left for a follow-up
since it requires POST /upload first.

Stack: feat/webchat-docs → feat/webchat-stream-e2e-test
Epic issue: #355
2026-06-18 06:33:17 +08:00