- Introduced `applyRequestAfterAuthInterceptor` to modify requests after credential selection and before executor translation. - Added `InterceptRequestAfterAuth` method across plugin adapters with corresponding tests for context validation. - Enhanced format resolution logic (`requestToFormat`) to support additional providers and formats. - Updated JavaScript handler to include a new `on_after_auth_request` hook for post-auth request handling. - Refactored interceptor methods for clarity and better encapsulation of request/response lifecycles.
JS Handler Plugin
A CLIProxyAPI plugin that executes external JavaScript scripts to intercept and modify requests, responses, and streaming chunks using the Goja VM engine.
Features
- Request Interception (
on_before_request,on_after_auth_request): Modify request payloads and headers before and after credential selection. - Response Interception (
on_after_nonstream_response): Modify non-streaming response bodies and headers. - Stream Chunk Interception (
on_after_stream_response): Modify individual streaming chunks with read-onlyhistory_chunkscontext. - Hot Reload: Scripts are automatically reloaded when modified on disk.
- Execution Timeout: Configurable timeout prevents infinite loops.
- Graceful Degradation: Original data is preserved on JS execution errors.
Configuration
plugins:
enabled: true
dir: "plugins-dir"
configs:
jshandler:
enabled: true
script_paths:
- /path/to/custom_handler.js
- ./relative_handler.js
timeout: 1s
Fields
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | true |
Enable or disable the plugin |
script_paths |
array | [] |
JS script file paths (absolute or relative to plugin directory) |
timeout |
string | 1s |
Execution timeout per JS hook call |
JS Script API
Scripts can export these global functions:
on_before_request(ctx)
Called before credential selection. At this point the target upstream protocol is not selected yet.
ctx structure:
{
"id": "request-id",
"body": "...", // Request body string
"headers": {}, // Request headers
"url": "",
"model": "gpt-4",
"protocol": "openai",
"source_format": "openai",
"sourceFormat": "openai",
"to_format": "",
"toFormat": ""
}
on_after_auth_request(ctx)
Called after credential selection and before request translation, request normalization, and built-in payload configuration.
ctx structure:
{
"id": "request-id",
"body": "...", // Request body string
"headers": {}, // Request headers
"url": "",
"model": "gpt-4",
"protocol": "openai", // Same as source_format
"source_format": "openai",
"sourceFormat": "openai",
"to_format": "codex",
"toFormat": "codex"
}
on_after_nonstream_response(ctx)
Called after a non-streaming response is received from upstream.
ctx structure (non-streaming):
{
"id": "request-id",
"body": "...", // Full response body
"req": { "body": "...", "headers": {}, "url": "" },
"protocol": "openai",
"headers": {},
"chunk": null,
"history_chunks": null
}
on_after_stream_response(ctx)
Called after each streaming response chunk is received from upstream.
ctx structure:
{
"id": "request-id",
"body": null,
"req": { "body": "...", "headers": {}, "url": "" },
"protocol": "openai",
"headers": {},
"chunk": "...", // Current writable chunk
"history_chunks": ["..."] // Read-only frozen array
}
Return Value
Return the modified ctx object, or a plain string to replace the body/chunk.
Built-in Scripts
The scripts/ directory contains built-in scripts loaded automatically:
copilot_handler.js: Fixes tool-callfinish_reasonfor GitHub Copilot compatibility.
Building
make build
The Makefile chooses the plugin extension from the target platform:
| GOOS | Output |
|---|---|
linux / freebsd |
jshandler.so |
darwin |
jshandler.dylib |
windows |
jshandler.dll |
You can override the target and output directory:
make build GOOS=darwin GOARCH=arm64 BUILD_DIR=/path/to/plugins/darwin/arm64