5 Commits

Author SHA1 Message Date
程序员阿江(Relakkes)
6818db34fb fix(desktop): overhaul touch-H5 interaction (#780)
Mark <html data-touch-h5> before first paint when the bundle runs in a
phone browser (no Electron host + coarse pointer) and scope every
mobile-only fix under it, so desktop shells and desktop browsers are
untouched:

- raise form controls to 16px and cap the iOS viewport scale, so
  focusing the composer no longer zooms the page and never zooms back
- disable content-visibility paint skipping on transcript/trace rows
  there (long-press selection on iOS WebKit jumps or drops selections
  when they extend into skipped rows); halve the virtualization
  thresholds on touch as the replacement paint bound for long sessions
- size the app shell to visualViewport so the composer rides the soft
  keyboard instead of being covered, snap back WebKit's keyboard pan,
  and keep the transcript tail pinned while the container shrinks
- pad the shell with safe-area insets (viewport-fit=cover) and drop the
  bottom inset while the keyboard is up
- keep message action bars (copy/branch) always visible on touch since
  hover never fires there; kill the WKWebView tap flash and body
  rubber-banding
- move the two inline content-visibility styles (trace message blocks,
  trace list rows) to classes so the touch scope can reach them

Tested: cd desktop && npx vitest run (1474 tests)
Tested: cd desktop && npx tsc --noEmit && npx vite build
Tested: Playwright chromium smoke against the built dist - desktop
context unchanged, iPhone/WeChat and Android contexts get the marker,
viewport lock, 16px controls, visible action bars and selectable rows
2026-06-13 09:16:37 +08:00
程序员阿江(Relakkes)
ea82c6ec70 fix(trace): record aborted API calls instead of leaving them pending (#766)
When an upstream request was aborted mid-stream (SDK client timeout,
stream idle watchdog, non-streaming fallback timeout, or user
cancellation), the trace fetch hook waited on a clone of the response
body that could hang forever, so the call never left "pending" in the
trace panel — exactly the silent stall that misled the #766 report.

- captureResponseTraceSnapshot reads the body with abort awareness:
  reader.cancel() on abort keeps the partial body, with a 2s grace
  backstop for runtimes where cancel cannot wake a hung read.
- The fetch hook now records an error-state call on abort with the
  abort reason (e.g. the watchdog's stream idle timeout), duration,
  partial response body, and an api_call_aborted event; non-abort
  capture failures also record an error instead of inferring ok, and
  pre-response fetch rejections carry an aborted flag.
- The trace detail panel shows an "Aborted" badge plus guidance for
  aborted calls, and labels the new api_call_aborted phase in all
  locales.

Tested: bun test src/server/__tests__/trace-capture.test.ts
Tested: bun run check:server
Tested: cd desktop && bun run test -- --run && bun run lint
2026-06-12 18:35:18 +08:00
程序员阿江(Relakkes)
00b4ead0ca fix(trace): show tool call durations (#799)
Compute tool spans from paired tool results, surface session wall/model/tool timing, and keep pending spans updated with elapsed time.

Tested: cd desktop && bun run test -- --run src/lib/traceViewModel.test.ts src/pages/TraceSession.test.tsx
Tested: cd desktop && bun run test -- --run src/pages/TraceList.test.tsx
Tested: bun run check:desktop
Scope-risk: narrow
2026-06-12 10:50:55 +08:00
程序员阿江(Relakkes)
ae32599ba8 fix(trace): stabilize live trace updates
Keep live trace polling sensitive to in-place call changes, scope detail section collapse state by trace session, and expose trace rows with list/button semantics.

Tested: cd desktop && bun run test -- TraceList.test.tsx TraceSession.test.tsx
Tested: cd desktop && bun run lint
Tested: bun test src/server/__tests__/trace-capture.test.ts
Confidence: medium
Scope-risk: narrow
2026-06-12 09:22:13 +08:00
程序员阿江(Relakkes)
d3d7566f0c refactor(trace): redesign trace UI with LangSmith-style two-pane layout
UI rebuild (desktop):
- TraceSession: replace 3-column layout with two panes — turn-grouped
  timeline tree (draggable splitter, search/filter, keyboard nav) and a
  section-flow detail panel (Response / Messages / System Prompt /
  Tools / Parameters / Raw), collapse state persists across spans
- Render LLM requests/responses semantically: messages as role-colored
  conversation with tool_use/tool_result pairing instead of raw JSON
  dumps; Raw fallback via CodeViewer for legacy truncated records
- TraceList: row-style list with model chips, mono metrics, hover
  actions; content-visibility rows (no virtualization, WebKit-safe)
- i18n synced across zh/en/jp/kr/zh-TW (+25/-55 keys)

Data & capture (server):
- Capture full bodies: preview cap 2048 -> 240k chars, stream cap
  256KB -> 1MB; list API trims previews to keep polling light; new
  GET /api/sessions/:id/trace/calls/:callId returns the full record
- Extract per-call token usage at read time (SSE + JSON + proxy
  wrapped); mtime-keyed read cache for the polling path
- Fix sensitive-key regex redacting *_tokens count fields, which made
  token stats always report 0

Frontend data layer:
- SSE stream reassembly (Anthropic + OpenAI chat) adapted from
  claude-tap (MIT, attribution in THIRD_PARTY_LICENSES.md), request/
  response body parsers, shared formatters, on-demand call detail
  cache; traceViewModel gains tokenUsage/isLifecycleNoise, drops
  fullRaw

Tested:
- bun run check:server (1201 pass)
- bun run check:desktop (lint + 1358 tests + build)
- Chromium walkthrough against real local traces: list, session tree,
  LLM semantic detail (new format), legacy fallback, tool detail
2026-06-11 01:02:51 +08:00