25 Commits

Author SHA1 Message Date
程序员阿江(Relakkes)
e6de5fde3a fix(provider): default provider requests to direct proxy mode (#953)
Refs: #896, #953

Make provider network proxy mode explicit so desktop sidecar system proxy env does not affect provider connectivity tests or OpenAI-compatible proxy requests unless System proxy is selected.

Tested: bun test src/server/__tests__/network-settings.test.ts src/server/__tests__/providers.test.ts src/server/__tests__/proxy-network-settings.test.ts
Tested: cd desktop && bun run test -- src/stores/settingsStore.test.ts src/__tests__/generalSettings.test.tsx --run
Tested: bun run check:server
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run build
Confidence: high
Scope-risk: moderate
2026-07-02 21:29:31 +08:00
程序员阿江(Relakkes)
2e52133a64 fix(provider): pass reasoning effort for proxies (#905)
Tested:
- bun test src/services/api/claudeEffort.test.ts src/server/__tests__/proxy-transform.test.ts src/utils/__tests__/thinking.test.ts
- bun run check:server
- git diff --check

Not-tested:
- bun run verify / coverage

Confidence: high
Scope-risk: narrow
2026-07-02 21:01:42 +08:00
程序员阿江(Relakkes)
9aaf3c9e5f fix: resolve desktop startup and provider regressions
Fixes #827, #857, #860, #885.

Reproduced #827 with a delayed pasted-image FileReader result that reappeared after send; fixed by invalidating stale paste callbacks after submit or session switch.

Reproduced #857 with TCP accepting while /health stayed unhealthy; fixed Electron sidecar readiness to require HTTP /health status ok before continuing.

Reproduced #860 through OpenAI-compatible sampling param pass-through and missing GLM-5.2 context metadata; fixed sampling params to be opt-in and added GLM-5.2 context windows for preset and core resolution.

Reproduced #885 with a truncated long sidebar title lacking a row tooltip; fixed by exposing the full title on the session row.

Tested: cd desktop && bun run test -- src/components/chat/ChatInput.test.tsx src/components/layout/Sidebar.test.tsx --run

Tested: cd desktop && bun test electron/services/sidecarManager.test.ts

Tested: bun test src/server/__tests__/proxy-transform.test.ts src/server/__tests__/provider-presets.test.ts src/services/compact/autoCompact.test.ts

Tested: bun run check:server

Tested: bun run check:desktop

Tested: bun run check:native

Confidence: high

Scope-risk: moderate
2026-06-23 00:38:28 +08:00
程序员阿江(Relakkes)
a090070352 fix(server): repair provider proxy and cron permissions
Fix #845 by starting a lightweight standalone provider proxy for CLI-only OpenAI-compatible desktop providers, avoiding a fixed localhost:3456 proxy when the desktop server is not running.

Fix #847 by passing explicit --permission-mode bypassPermissions for scheduled task subprocesses alongside the dangerous-skip flag.

Tested: bun test src/utils/managedEnv.test.ts src/server/__tests__/provider-runtime-env.test.ts src/server/__tests__/cron-scheduler-launcher.test.ts

Tested: bun run check:server

Confidence: high

Scope-risk: moderate
2026-06-22 23:45:15 +08:00
程序员阿江(Relakkes)
2f8c2a9a70 fix: resolve first issue 809 batch
Fixes local Batch A from #809+ triage: configurable scheduled task timeout (#809/#846), OpenAI proxy trace request headers (#836), title generation auth strategy (#854), and unresolved parallel tool card settlement (#889).

Tested: bun test src/server/__tests__/cron-scheduler-launcher.test.ts

Tested: bun test src/server/__tests__/title-service.test.ts

Tested: bun test src/server/__tests__/proxy-network-settings.test.ts

Tested: cd desktop && bun run test -- --run src/stores/chatStore.test.ts

Tested: bun run check:server

Tested: bun run check:desktop

Not-tested: bun run verify and coverage were not run because this is a local batch checkpoint, not a PR-ready/push-ready handoff.

Confidence: high

Scope-risk: moderate
2026-06-22 22:45:26 +08:00
程序员阿江(Relakkes)
3d02e3a91a fix(proxy): establish OpenAI prompt cache semantics (#789)
Strip the rotating billing attribution line before converting system
prompts to OpenAI Chat/Responses requests, forward a stable
prompt_cache_key derived from the client session, request stream usage
explicitly on Chat streams, and map cached_tokens back to Anthropic
cache_read_input_tokens with exclusive input accounting.
2026-06-12 12:28:26 +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
程序员阿江(Relakkes)
0d45439fbe feat(trace): add session trace monitoring (#606)
Tested:
- cd desktop && bun run test -- --run src/pages/TraceList.test.tsx
- bun test src/server/__tests__/trace-capture.test.ts
- bun run check:desktop
- bun run check:server

Scope-risk: broad
2026-06-10 17:13:27 +08:00
程序员阿江(Relakkes)
e8bf789961 fix(provider): request non-stream OpenAI chat tests (#638)
Ensure custom OpenAI-compatible provider tests explicitly request non-stream responses for both direct connectivity checks and the proxy pipeline. This avoids default SSE responses being parsed as empty JSON by provider validation.

Tested: bun test src/server/__tests__/providers.test.ts --test-name-pattern "requests non-stream OpenAI Chat responses during provider tests"
Tested: bun test src/server/__tests__/providers.test.ts
Tested: bun test src/server/__tests__/proxy-transform.test.ts
Tested: bun run check:server
Confidence: high
Scope-risk: narrow
2026-06-09 22:16:38 +08:00
程序员阿江(Relakkes)
4a53a1659f fix(proxy): timeout stalled OpenAI-compatible streams (#548)
Guard OpenAI-compatible proxy streaming bodies with the configured AI request timeout so a provider that emits partial SSE and then idles cannot leave proxy consumers waiting forever.

This is a proxy-level fix found while investigating #548; it does not claim to close the broader desktop interruption issue.

Tested: bun test src/server/__tests__/proxy-network-settings.test.ts

Tested: bun run check:server

Confidence: medium

Scope-risk: narrow
2026-06-04 22:27:04 +08:00
程序员阿江(Relakkes)
264b24a462 fix: make provider tests match chat model normalization (#620)
Provider connectivity checks and proxy validation are API boundaries, but they kept the user-facing context suffix in the model id while the chat runtime already strips it. Normalize these paths so MiMo-style models with [1m] test the same model that sessions send.

Constraint: [1m]/[2m] are client-side context markers and upstream APIs may reject them
Rejected: Strip suffixes when saving provider config | would change the user-visible model selection instead of only the API boundary
Confidence: high
Scope-risk: narrow
Directive: Keep all provider API boundaries aligned with normalizeModelStringForAPI before sending requests upstream
Tested: bun test src/server/__tests__/providers.test.ts --test-name-pattern "normalizes context-window suffixes"
Tested: bun test src/server/__tests__/providers.test.ts
Tested: bun run check:server
Tested: git diff --check
Not-tested: Live MiMo API call; no provider credential was used
Related: #620
2026-06-01 20:03:53 +08:00
程序员阿江(Relakkes)
99caf8fdf5 fix: avoid DeepSeek OpenAI image_url rejection
DeepSeek's OpenAI-compatible chat schema accepts text content rather than OpenAI vision content parts, so forwarding Anthropic image blocks as image_url makes the upstream reject the request before the model can answer. Keep normal OpenAI Chat vision behavior as the default, but switch known DeepSeek-compatible chat proxy requests to a text-only conversion that preserves prompt text and replaces image payloads with a small omission marker.

Constraint: DeepSeek official Chat Completions docs list user message content as string text, while its Anthropic compatibility table marks image blocks as not supported.

Rejected: Expand unsupported-image error string matching only | it still surfaces the first turn as an API error and depends on provider wording.

Confidence: high

Scope-risk: narrow

Tested: bun test src/server/__tests__/proxy-transform.test.ts

Tested: bun test src/server/__tests__/providers.test.ts --test-name-pattern "handleProxyRequest|omits image_url"

Tested: bun test src/services/api/errors.test.ts tests/mediaRecoveryAndEstimation.test.ts

Tested: bun run check:server
2026-06-01 00:11:44 +08:00
程序员阿江(Relakkes)
5f3da46354 fix: keep OpenAI proxy streams past request timeout
OpenAI-compatible streaming requests previously used the shared AI request timeout as a full-body AbortSignal. That made long SSE generations stop mid-answer after the configured timeout even when the upstream had already started streaming.

The proxy now applies the configured timeout only while opening streaming upstream requests and keeps non-streaming requests on the existing full-request timeout.

Constraint: The global AI request timeout is documented as covering provider requests and streaming first responses, not total stream duration.
Rejected: Increase the default timeout | long plan-mode answers can still exceed any fixed full-stream limit.
Confidence: high
Scope-risk: narrow
Tested: bun test src/server/__tests__/proxy-network-settings.test.ts
Tested: bun run check:server
2026-05-23 14:10:58 +08:00
程序员阿江(Relakkes)
a159ee3511 fix: stream ChatGPT OAuth title requests
ChatGPT Codex requires streamed Responses API requests, including hidden non-chat paths such as title generation. Keep the OAuth adapter streaming upstream while preserving JSON responses for non-streaming Anthropic callers, and route ChatGPT Official titles through the OAuth Codex endpoint.

Constraint: ChatGPT Codex rejects non-streaming requests with HTTP 400
Rejected: Disable AI title generation for ChatGPT OAuth | would leave first-session metadata degraded
Confidence: high
Scope-risk: narrow
Tested: bun test src/services/openaiAuth/fetch.test.ts
Tested: bun test src/server/__tests__/title-service.test.ts
Tested: bun run check:server
Tested: git diff --check
Not-tested: Live ChatGPT OAuth account round trip after remote build
2026-05-21 15:31:56 +08:00
程序员阿江(Relakkes)
4343b3f039 fix: Make General proxy timeout authoritative
Non-stream OpenAI-compatible proxy requests still kept the previous 300s timeout floor after the unified network settings merge. That made lower General AI timeout settings ineffective for normal proxy traffic, even though the setting is meant to be the final provider request timeout.

Constraint: Unified network settings must remain the final timeout and proxy override for provider protocol paths.
Rejected: Keep the 300s non-stream floor | it makes low timeout settings ineffective for normal proxy requests.
Confidence: high
Scope-risk: narrow
Directive: Do not reintroduce per-protocol timeout floors without updating the General network settings contract and tests.
Tested: bun test src/server/__tests__/proxy-network-settings.test.ts
Tested: bun test src/server/__tests__/conversation-service.test.ts src/server/__tests__/network-settings.test.ts src/server/__tests__/providers.test.ts src/server/__tests__/proxy-network-settings.test.ts
Tested: bun run check:coverage
Tested: bun run verify
Not-tested: Live provider request against a real upstream proxy.
2026-05-20 17:48:01 +08:00
程序员阿江(Relakkes)
88ac83d42f Merge unified AI network settings into main
The worktree implementation adds one General settings surface for AI request timeout and proxy configuration. This merge keeps main's newer attribution-signing and ChatGPT Official provider paths while preserving the unified network override across CLI sessions, provider checks, and OpenAI-compatible proxy forwarding.

Constraint: Main had newer attribution and official-provider changes touching the same server integration points
Rejected: Prefer the worktree proxy body verbatim | it would drop main's signed CCH attribution wrapper
Rejected: Keep provider preset timeouts above General | it would violate the single timeout control requirement
Confidence: high
Scope-risk: moderate
Directive: General network settings must remain the final AI request timeout and proxy override for every provider protocol
Tested: bun test src/server/__tests__/conversation-service.test.ts src/server/__tests__/network-settings.test.ts src/server/__tests__/providers.test.ts src/server/__tests__/proxy-network-settings.test.ts
Tested: cd desktop && bun run test -- --run src/stores/settingsStore.test.ts src/__tests__/generalSettings.test.tsx
Not-tested: Full bun run verify after resolving main merge conflicts
2026-05-20 17:30:10 +08:00
程序员阿江(Relakkes)
df60c77472 fix: add Claude Code billing attribution compatibility 2026-05-19 22:35:05 +08:00
程序员阿江(Relakkes)
8b7abb41b7 feat: Add unified AI network settings
Settings General now owns AI request timeout and proxy policy so Anthropic-native and OpenAI-compatible provider paths share one user-visible control. The desktop UI persists the network settings, the server proxy and provider checks read them directly, and CLI sessions receive the same timeout/proxy environment.

Constraint: Provider request behavior must be consistent across Anthropic, OpenAI Chat, and OpenAI Responses formats
Rejected: Keep preset API_TIMEOUT_MS precedence | it would make the General timeout control unreliable for some providers
Confidence: high
Scope-risk: moderate
Directive: Do not add protocol-specific AI request timeout controls without preserving General as the final override
Tested: bun test src/server/__tests__/conversation-service.test.ts src/server/__tests__/network-settings.test.ts src/server/__tests__/providers.test.ts src/server/__tests__/proxy-network-settings.test.ts
Tested: cd desktop && bun run test -- --run src/stores/settingsStore.test.ts src/__tests__/generalSettings.test.tsx
Tested: bun run check:desktop
Tested: bun run check:server
Not-tested: socks5 manual proxy support; manual proxy validation currently accepts HTTP/HTTPS URLs only
2026-05-19 17:48:05 +08:00
程序员阿江(Relakkes)
63ef7b1a5b Preserve DeepSeek reasoning history for OpenAI chat proxies
DeepSeek-compatible OpenAI Chat providers require assistant reasoning_content to be replayed on later tool-call turns when thinking mode is active. The Anthropic-to-OpenAI chat transform now keeps that replay behavior behind an explicit compatibility option, and the proxy only enables it for DeepSeek/OpenCode base URLs so generic OpenAI-compatible providers keep their previous request shape.

Constraint: DeepSeek thinking mode rejects follow-up requests when prior assistant reasoning_content is omitted

Rejected: Trigger compatibility by model name | would affect unrelated OpenAI-compatible providers using DeepSeek model ids

Confidence: high

Scope-risk: narrow

Directive: Do not broaden this compatibility gate without proving other OpenAI-compatible providers accept these non-standard fields

Tested: Fixed-port Web UI harness with copied DeepSeek OpenAI Chat provider reproduced the 400 and passed through local proxy after the fix

Tested: bun test src/server/__tests__/proxy-transform.test.ts

Tested: bun run check:server

Tested: git diff --check

Not-tested: Direct OpenCode Go subscription endpoint, unavailable locally
2026-05-19 17:40:43 +08:00
546657701
3759588f5b fix: openaiResponsesToAnthropic usage fallback for OpenAI-compatible APIs
Non-streaming adapter only read `output_tokens`/`input_tokens` (Anthropic-style),
but many OpenAI-compatible providers (e.g. Jiutian MoMA) return standard
`completion_tokens`/`prompt_tokens` fields. This caused a null reference
error when reading `output_tokens` from such responses.

The streaming adapter already handles `completion_tokens` correctly, and
the Azure adapter uses the same fallback pattern applied here.

Fixes #383

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 19:02:10 +08:00
程序员阿江(Relakkes)
f9f1f20e99 Fix local proxy tool calls for real provider responses
Local OpenAI-compatible proxies can return function arguments as parsed objects instead of JSON strings. Preserve object-shaped arguments directly and serialize them for streaming deltas so Write, Bash, and Edit tool calls keep the fields required by Anthropic tool validation.

Constraint: Local proxy implementations such as OneAPI/NewAPI may not preserve OpenAI's string-only arguments shape.
Rejected: Normalize every upstream response through JSON.stringify before parsing | loses already-valid object identity and leaves streaming object deltas vulnerable to [object Object].
Confidence: high
Scope-risk: narrow
Directive: Do not assume function.arguments is always a string on provider responses or stream deltas.
Tested: bun test src/server/__tests__/proxy-streaming.test.ts src/server/__tests__/proxy-transform.test.ts
Tested: bun run check:server
Tested: bun run check:native
Tested: bun run quality:pr
Tested: agent-browser with real Ollama qwen3:4b provider for Write/Bash/Edit and streaming Write
Not-tested: Real Windows OneAPI/NewAPI instance from the issue reporters was not available locally.
2026-05-06 11:39:10 +08:00
cynicalight
9204317307 fix: /context command to display the correct context window for gpt 2026-05-04 16:45:59 +08:00
cynicalight
f091e8e5a5 feat: openai auth login via cli 2026-05-04 16:45:24 +08:00
程序员阿江(Relakkes)
773a8a703f Keep desktop chats on the selected provider/model
The desktop model picker now stores a session-scoped provider/model selection instead of relying on the global active provider. That selection is replayed on connect, passed into the CLI startup path, and preserved across turns until the user changes it again.

To make that true end-to-end, the server now restarts the session process when runtime selection changes, injects provider-scoped env for third-party providers, and routes proxy traffic by provider id. The selector UI was also tightened so provider grouping stays visible while the actual model choice remains readable.

Constraint: Different providers can expose the same model id, so chat runtime selection cannot be derived from model id alone
Constraint: A desktop session reuses one CLI subprocess across turns, so runtime changes must restart that process to take effect
Rejected: Keep using Settings active provider as the chat selector | conflates defaults with live session state and breaks overlapping models
Rejected: UI-only runtime switching without server restart | later turns would continue using the old CLI subprocess configuration
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep provider defaults and session runtime overrides separate, and preserve provider-scoped proxy routing when extending model selection surfaces
Tested: cd desktop && bun run lint
Tested: cd desktop && bun run test src/stores/chatStore.test.ts
Tested: cd desktop && bun run test src/__tests__/generalSettings.test.tsx
Tested: bun test src/server/__tests__/conversation-service.test.ts
Tested: bun test src/server/__tests__/conversations.test.ts
Tested: bun -e "await import('./src/server/services/titleService.ts'); await import('./src/server/ws/handler.ts')"
Not-tested: Real third-party provider round-trip from the desktop UI against a live upstream account
2026-04-23 13:41:27 +08:00
程序员阿江(Relakkes)
98a24f99b4 feat(proxy): add multi-protocol proxy for OpenAI-compatible providers
Add a protocol-translating reverse proxy that allows using OpenAI-compatible
API providers (DeepSeek, OpenRouter, Groq, etc.) with Claude Code.

The proxy intercepts Anthropic Messages API requests from the CLI, transforms
them to OpenAI Chat Completions or Responses API format, forwards to the
upstream provider, and transforms streaming/non-streaming responses back.

Key features:
- Request transform: Anthropic Messages → OpenAI Chat/Responses
- Response transform: OpenAI → Anthropic (streaming SSE + non-streaming)
- Provider-agnostic reasoning support (reasoning_content, thinking_blocks,
  reasoning fields from DeepSeek, OpenAI o-series, GLM-5, Groq, etc.)
- Event queue pattern for correct Anthropic SSE event ordering
- Two-step test: ① connectivity check ② full proxy pipeline validation
- Desktop UI: API format selector, two-step test results display
- License attribution for cc-switch (MIT, Jason Young)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 00:33:26 +08:00