Commit Graph

85 Commits

Author SHA1 Message Date
sususu
580df36423 feat(usage): propagate session and parent session hierarchy to usage reporting queue
- Reuse coresession.ExtractSessionInfo across HTTP headers and request payloads to unify canonical session prefix namespaces with the scheduler.
- Extract hierarchical session identities in two phases: initial extraction from request headers on entry, and authoritative deep extraction once request payloads and metadata are available.
- Support Claude Code multi-level subagents (X-Claude-Code-Agent-Id, metadata.agent_id) and Codex thread fork lineages.
- Propagate SessionID and ParentSessionID across ClientRequestMetadata, UsageReporter, and coreusage.Record without root_session_id.
- Include session_id and parent_session_id in queuedUsageDetail for Home LPushUsage forwarding and Redis consumption with self-loop guards.
- Add comprehensive test coverage for canonical headers, body extraction, ghost parent elimination, and self-referential loop guards.
2026-09-06 10:45:32 +08:00
Luis Pater
02c02cda50 fix: harden concurrent session handling, listener lifecycle, and token accounting
- Use `context.AfterFunc` and buffered delivery in websocket relay sessions to avoid per-request goroutine leaks.
- Synchronize in-flight puts and drain queued connections upon mux listener close.
- Ensure home streaming log writer goroutines terminate cleanly when the log client is unhealthy.
- Prevent integer arithmetic overflow in token breakdown validations and calculations.
- Clone request headers in logging middleware to prevent concurrent mutation issues.
- Implement standard `io.WriterTo` return signature for file body sources.

Closes: #4709
2026-09-02 20:02:42 +08:00
hkfires
e4a8f98913 fix(logging): enhance error diagnostics and logging for home refresh operations 2026-08-29 12:50:45 +08:00
hkfires
9a2201c36a fix(auth): forward Home unauthorized upstream errors
Stop refreshing Home-owned OAuth credentials after upstream 401s.
Preserve marked upstream response bodies for direct responses, usage
records, request logs, and websocket handshake failures.
2026-08-29 12:50:44 +08:00
sususu98
ca601db05d feat: observe upstream provider quota signals (#5211)
Codex and Claude already emit credential-level quota watermarks on ordinary
responses. CPA used to drop them. Keep the latest watermark in memory and
return it from the management auth-file API.

Hard rule: this is observation only. It must not change scheduling, cooldown
selection, or auth-file persistence.

Snapshot, not accumulation
- QuotaState now has ObservedAt and a bounded Signals map. MarkResult fills
  them from the response headers already recorded on the request.
- Signals is the current response, not a union of earlier ones. Retry-After
  and "limit reached" only appear on the response that produced them; merging
  across responses would keep an expired value forever.
- A response with no quota header (transport failure, 5xx, unrelated endpoint)
  leaves the previous snapshot in place.
- ObservedAt is the time of the current snapshot. It advances even when the
  values did not change, so a consumer can tell a fresh reading from a stale
  one.
- When two model states merge, keep the newer snapshot. Do not union keys
  captured at different times.

What is observed, and what is not
- One predicate, ProviderSupportsQuotaObservation, decides the provider set.
- Keep Codex and Claude. Drop Kimi, xAI/Grok, Antigravity, and the Gemini
  family (gemini/vertex/aistudio): their ordinary headers are not a reliable
  credential-level remaining quota.
- Count-tokens reuses the credential but is not generation traffic.
  ExecuteCount sets SkipQuotaObservation so those headers cannot replace the
  last generation snapshot. Cooldown and success/failure accounting still run.

Cooldown must not overwrite the last snapshot
- Observation writes only ObservedAt and Signals.
- Cooldown writes only Exceeded, Reason, NextRecoverAt, and BackoffLevel,
  through applyCooldownFields. Never assign a fresh QuotaState{...} over a
  live value: that would zero the snapshot on 429, Cloudflare, credential-
  scope sibling updates, and cooldown clears.
- If a credential-quota cooldown is still active, MarkResult still observes
  an already-present model state. It does not create scheduler state just to
  record a watermark.
- .cds files persist cooldownFieldsOf(Quota) only. Restore keeps the newer
  ObservedAt, so reloading cooldown cannot clobber a newer in-memory snapshot.
- cooldownQuotaEqual still ignores observation fields, so a watermark change
  cannot by itself persist cooldown or move the scheduler.
- The management payload omits every cooldown field, so it cannot be mistaken
  for scheduler state or wired back into scheduling.
- Manual ResetQuota still clears the full QuotaState.

Codex websocket events
- Codex WS reports quota as codex.rate_limits frames, not HTTP headers.
  ParseCodexQuotaEventHeaders turns one event into the same bounded header
  shape, and MergeResponseHeaders folds it into the request-scoped holder.
  additional_rate_limits is accepted as an object (websocket) or an array
  (/wham/usage).
- Parse only through AppendCodexAPIWebsocketResponse. The shared
  AppendAPIWebsocketResponse is also used by xAI, and xAI error frames really
  do carry x-ratelimit-* headers. Parsing every frame as Codex quota would
  forge Codex headers into another provider's request log.
- Also capture code_review_rate_limits.
- A malformed active-limit name drops only that one header, not the window
  watermarks parsed from the same event.
- The type discriminator scans a bounded frame prefix, not every byte of
  every frame.
- HTTP namespaces an extra limit by short name (x-codex-bengalfox-*); WS
  namespaces it by limit name (GPT-5.3-Codex-Spark). The two paths cannot
  emit the same header names. The X-Codex-Additional- prefix marks the WS
  origin, and snapshot replacement keeps the two spellings from piling up.

Hardening
- Reject observed values with control characters. These strings reach the
  plain-text request log, and Limit-Name is upstream-controlled, so CR/LF
  could forge a header line.
- When the header cap is hit, keep plan/credits/primary ahead of
  additional-limit namespaces, then sort names so truncation is deterministic.
- QuotaState.Clone deep-copies Signals and is used by Auth.Clone and
  ModelState.Clone.
- Token stores still serialize credential metadata only, so observation adds
  no auth-file writes.
2026-08-24 17:15:37 +08:00
Luis Pater
c9417c8ae9 feat(logging): add client request metadata extraction and propagation
- Added `ClientRequestMetadata` struct to capture client IP, `X-Forwarded-For` headers, and user agent.
- Implemented metadata extraction in HTTP handlers and propagation through context.
- Updated Redis queue plugin to include client request metadata in payloads.
- Added tests to validate metadata extraction and inclusion in request contexts.
2026-07-28 16:34:15 +08:00
Luis Pater
fe4ae4989c chore(pluginhost): refactor and remove unused interceptors and executor methods
- Removed deprecated interceptor and executor-related methods, including `callRequestInterceptor`, `callResponseInterceptor`, and `callStreamChunkInterceptor`.
- Consolidated unused logic and pruned redundant imports to streamline `adapters.go`.
- No functional changes.
2026-07-26 14:31:45 +08:00
Luis Pater
f8dffa0522 feat(logging): log Codex media forwarding start with detailed fields
- Implemented logging for Codex remote media forwarding start events, including detailed connection and credential metadata.
- Added `formatLogFieldValue` for quoting specific log fields and ensured newline safety in log output.
- Enhanced unit tests to validate log content, escaping, and field inclusion.
2026-07-25 07:51:43 +08:00
Luis Pater
3ecd4afe80 feat: add Home credential concurrency support 2026-07-23 13:42:08 +08:00
Luis Pater
366271969a feat(logging): add CPA trace ID middleware and enhance metadata handling
- Introduced CPA trace ID middleware to inject trace IDs in response headers.
- Added support for CPA trace ID generation and validation.
- Updated metadata handling to include stable auth indices and trace ID callbacks for enhanced request tracking.
- Enhanced tests to verify CPA trace ID propagation and reserved header handling across middleware, metadata, and handlers.

Closes: #4370
2026-07-17 22:58:28 +08:00
Luis Pater
e57416731a feat(logging): add deferred request body capture for error handling
- Introduced `deferredRequestBodyCapture` for spooling and retaining large error-only request bodies for improved logging.
- Enhanced `RequestLoggingMiddleware` to capture request body based on size and error criteria.
- Implemented decompression and truncation for large request bodies with Zstd encoding.
- Added support for deferred API request logging and context tracking.
- Included extensive test coverage for error-specific body capture and serialization behavior.
2026-07-14 23:35:29 +08:00
hkfires
6a59d645b5 feat(pluginhost): enhance plugin version management and logging for hot reload 2026-06-26 12:05:07 +08:00
hkfires
192888f9b1 feat(pluginhost): enhance logging with plugin name and path fields 2026-06-25 20:51:20 +08:00
Luis Pater
7de9757c82 feat: add OpenAI video support with improved error handling and response normalization
- Introduced `/openai/v1/videos` endpoint to support OpenAI-specific video generation.
- Added error normalization and handling for OpenAI video resources, including detailed error propagation.
- Enhanced response structure to include OpenAI-specific fields for status, progress, and model mappings.
- Implemented new handlers for video content retrieval and error scenarios.
- Expanded test coverage to validate OpenAI video support, error handling, and backend compatibility.
2026-06-15 01:53:52 +08:00
hkfires
8122b9fe4b feat!: remove amp integration support
BREAKING CHANGE: ampcode configuration, management endpoints, provider
routing, and X-Amp-Thread-Id session affinity are no longer supported
2026-06-14 20:31:00 +08:00
shoucandanghehe
dc3152d2e3 fix(logging): tighten Codex backend request ID prefix 2026-06-10 01:29:42 +08:00
shoucandanghehe
e1864fbf33 fix(logging): track Codex backend request IDs 2026-06-10 01:05:09 +08:00
sususu98
c7cc3a1a4d fix: update antigravity version lookup 2026-06-09 11:32:57 +08:00
Luis Pater
5753d1a089 feat(logging): enable file-backed request/response sources for enhanced API logging
- Introduced support for file-backed logging of API requests and responses to handle large payloads efficiently.
- Refactored `attachWebsocketLogSources` to `attachRequestLogSources` for broader request and response handling.
- Added new methods for appending request/response data to file-backed sources and updated existing logging workflows for compatibility.
- Improved cleanup and merge logic for file-backed sources during request processing.
- Updated tests to cover newly introduced file-backed logging functionality.
2026-06-05 01:48:05 +08:00
hkfires
d2c5f279f6 feat(logging): add request_id handling in HomeAppLogForwarder and tests 2026-05-29 10:58:19 +08:00
hkfires
c4ee063b95 feat(logging): add HomeAppLogForwarder for application log forwarding 2026-05-29 08:12:52 +08:00
Luis Pater
2bcc76220c feat(logging): improve file-backed source cleanup and directory recreation logic
- Added `assertFileBodySourceCleaned` helper to streamline cleanup validations in tests.
- Introduced handling to recreate missing directories during file source operations.
- Enhanced tests to verify behavior after manual directory removal, ensuring robustness.
- Fixed edge cases in log file merging when parts are missing.
2026-05-28 10:42:24 +08:00
Luis Pater
a0bb1f3a2b feat(logging): add file-backed sources for request logging
- Introduced `FileBodySource` to support large request log sections stored in temp files.
- Added file-backed support for WebSocket timeline and API WebSocket timeline logging.
- Updated `LogRequest` and middleware to integrate optional file-backed sources.
- Implemented clean-up mechanisms to manage temporary log files after processing.
2026-05-25 21:55:16 +08:00
Luis Pater
412d3442fa feat(logging): add RequestID support in home request logging
- Included `RequestID` field in `homeRequestLogPayload` for better log categorization.
- Updated `forwardRequestLogToHome` and related components to handle `RequestID`.
- Added new test cases to validate `RequestID` propagation in streaming requests.
2026-05-25 20:44:32 +08:00
Luis Pater
ad98c9549a feat(runtime): track upstream response headers in logging and usage reporting
- Added APIs to store, retrieve, and clone upstream response headers in context for detailed logging.
- Updated `RecordAPIResponseMetadata`, `RecordAPIWebsocketHandshake`, and related methods to capture response headers.
- Extended `UsageReporter` to include response headers in published usage records.
- Enhanced payload tests to validate response headers' integrity and persistence.
- Refactored `usage.Record` to support optional `ResponseHeaders` field.
2026-05-19 01:29:23 +08:00
Luis Pater
53d1fd6c5c feat(api, xai): add xAI Grok video model support with API integration
- Introduced new xAI `grok-imagine-video` model for video generation with configurable options (e.g., duration, size, resolution).
- Implemented video-specific API endpoints (`/v1/videos`, `/v1/videos/generations`, `/v1/videos/edits`, `/v1/videos/extensions`), including request validation and model handling.
- Enhanced model registry with `xaiBuiltinVideoModelID` and metadata for video capabilities.
- Added unit tests to validate video model support, request structures, and API response handling.
- Extended `XAIExecutor` to integrate video generation and retrieval via runtime requests.
2026-05-17 02:53:50 +08:00
Luis Pater
1abf8625d8 feat(logging): add home request-log forwarding support
- Introduced `SetHomeEnabled` to enable/disable request-log forwarding to the home control plane.
- Implemented `forwardRequestLogToHome` for non-streaming logs and `homeStreamingLogWriter` for real-time streaming logs.
- Enhanced `FileRequestLogger` to bypass local logging when home forwarding is enabled.
- Updated server configuration to dynamically toggle home request-log forwarding based on changes.
- Added corresponding unit tests to ensure correct forwarding behavior and fallback mechanisms.
2026-05-09 23:39:59 +08:00
Luis Pater
e50cabac4b chore: upgrade CLIProxyAPI dependency to v7 across the project
- Updated all references from v6 to v7 for `github.com/router-for-me/CLIProxyAPI`.
- Ensured consistency in imports within core libraries, tests, and integration tests.
- Added missing tests for new features in Redis Protocol integration.
2026-05-08 11:46:46 +08:00
Luis Pater
4035abc0cd refactor(logging): replace gin-specific context handling with generic context-based request metadata utilities
- Introduced reusable utilities in `requestmeta` to manage endpoint and response status in request contexts.
- Refactored plugins and handlers to use context-based metadata, removing direct dependency on `gin`.
- Updated tests to validate new context utilities and replaced `gin`-based context handling.

Fixed: #3166
2026-04-30 23:36:07 +08:00
sususu98
6fc23568df logging: mark antigravity credits requests 2026-04-26 23:04:27 +08:00
Luis Pater
25137b1984 feat(logging): add AI API path support for image routes
- Included `/v1/images` in AI API path prefixes.
- Introduced tests to validate `/v1/images/generations` and `/v1/images/edits` as AI API paths.
2026-04-24 00:11:42 +08:00
hkfires
4f8acec2d8 refactor(logging): centralize websocket handshake recording 2026-04-02 18:39:32 +08:00
hkfires
34339f61ee Refactor websocket logging and error handling
- Introduced new logging functions for websocket requests, handshakes, errors, and responses in `logging_helpers.go`.
- Updated `CodexWebsocketsExecutor` to utilize the new logging functions for improved clarity and consistency in websocket operations.
- Modified the handling of websocket upgrade rejections to log relevant metadata.
- Changed the request body key to a timeline body key in `openai_responses_websocket.go` to better reflect its purpose.
- Enhanced tests to verify the correct logging of websocket events and responses, including disconnect events and error handling scenarios.
2026-04-02 17:30:51 +08:00
Cyrus
a275db3fdb fix(logging): expand tilde in auth-dir and log resolution errors
- Use util.ResolveAuthDir to properly expand ~ to user home directory
- Fixes issue where logs were created in literal "~/.cli-proxy-api" folder
- Add warning log when auth-dir resolution fails for debugging

Bug introduced in 62e2b67 (refactor(logging): centralize log directory
resolution logic), where strings.TrimSpace was used instead of
util.ResolveAuthDir to process auth-dir path.
2026-02-03 00:02:54 +08:00
sususu98
6db8d2a28e feat(logging): make error-logs-max-files configurable
- Add ErrorLogsMaxFiles config field with default value 10
- Support hot-reload via config file changes
- Add Management API: GET/PUT/PATCH /v0/management/error-logs-max-files
- Maintain SDK backward compatibility with NewFileRequestLogger (3 params)
- Add NewFileRequestLoggerWithOptions for custom error log retention

When request logging is disabled, forced error logs are retained up to
the configured limit. Set to 0 to disable cleanup.
2026-01-31 17:48:40 +08:00
sususu98
295f34d7f0 fix(logging): capture streaming TTFB on first chunk and make timestamps required
- Add firstChunkTimestamp field to ResponseWriterWrapper for sync capture
- Capture TTFB in Write() and WriteString() before async channel send
- Add SetFirstChunkTimestamp() to StreamingLogWriter interface
- Make requestTimestamp/apiResponseTimestamp required in LogRequest()
- Remove timestamp capture from WriteAPIResponse() (now via setter)
- Fix Gemini handler to set API_RESPONSE_TIMESTAMP before writing response

This ensures accurate TTFB measurement for all streaming API formats
(OpenAI, Gemini, Claude) by capturing timestamp synchronously when
the first response chunk arrives, not when the stream finalizes.
2026-01-29 22:32:24 +08:00
sususu98
c41ce77eea fix(logging): add API response timestamp and fix request timestamp timing
Previously:
- REQUEST INFO timestamp was captured at log write time (not request arrival)
- API RESPONSE had NO timestamp at all

This fix:
- Captures REQUEST INFO timestamp when request first arrives
- Adds API RESPONSE timestamp when upstream response arrives

Changes:
- Add Timestamp field to RequestInfo, set at middleware initialization
- Set API_RESPONSE_TIMESTAMP in appendAPIResponse() and gemini handler
- Pass timestamps through logging chain to writeNonStreamingLog()
- Add timestamp output to API RESPONSE section

This enables accurate measurement of backend response latency in error logs.
2026-01-29 22:22:18 +08:00
Luis Pater
a4f8015caa test(logging): add unit tests for GinLogrusRecovery middleware panic handling 2026-01-21 10:57:27 +08:00
hkfires
cb6caf3f87 fix(thinking): update ValidateConfig to include fromSuffix parameter and adjust budget validation logic 2026-01-18 16:37:14 +08:00
Luis Pater
f88228f1c5 Merge pull request #1081 from router-for-me/thinking
Refine thinking validation and cross‑provider payload conversion
2026-01-18 13:34:28 +08:00
Luis Pater
62e2b672d9 refactor(logging): centralize log directory resolution logic
- Introduced `ResolveLogDirectory` function in `logging` package to standardize log directory determination across components.
- Replaced redundant logic in `server`, `global_logger`, and `handlers` with the new utility function.
2026-01-18 12:40:57 +08:00
hkfires
03005b5d29 refactor(thinking): add Gemini family provider grouping for strict validation 2026-01-18 11:30:53 +08:00
hkfires
4ad6189487 refactor(thinking): extract antigravity logic into a dedicated provider 2026-01-15 19:08:22 +08:00
hkfires
1fbbba6f59 feat(logging): order log fields for improved readability 2026-01-15 13:06:41 +08:00
hkfires
f6a2d072e6 refactor(thinking): refine configuration logging 2026-01-15 13:06:41 +08:00
Luis Pater
f6ab6d97b9 fix(logging): add isDirWritable utility to enhance log dir validation in ConfigureLogOutput 2025-12-30 10:48:25 +08:00
Luis Pater
bc866bac49 fix(logging): refactor ConfigureLogOutput to accept config object and adjust log directory handling 2025-12-30 10:28:25 +08:00
Soff
44b63f0767 fix: Return an error if the user home directory cannot be determined for the fallback log path. 2025-12-29 18:46:15 +08:00
Soff Chen
6705d20194 fix: Implement fallback log directory for file logging on read-only systems. 2025-12-29 18:35:48 +08:00
hkfires
5ba325a8fc refactor(logging): standardize request id formatting and layout 2025-12-24 22:03:07 +08:00