mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-09-03 06:35:00 +08:00
fix(pluginhost): detach context and log rpc failures in usage handling
- Detach cancellation from context before dispatching usage records to plugins. - Log debug messages when RPC `usage.handle` calls fail. Closes: #5244
This commit is contained in:
@@ -2283,6 +2283,49 @@ func TestUsageAdapterPreservesExplicitGenerateFalse(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUsageAdapterDetachesContext(t *testing.T) {
|
||||
var receivedCtx context.Context
|
||||
plugin := usagePluginFunc(func(ctx context.Context, record pluginapi.UsageRecord) {
|
||||
receivedCtx = ctx
|
||||
})
|
||||
host := newHostWithRecords(capabilityRecord{
|
||||
id: "usage-detach",
|
||||
plugin: pluginapi.Plugin{Capabilities: pluginapi.Capabilities{
|
||||
UsagePlugin: plugin,
|
||||
}},
|
||||
})
|
||||
adapter := &usageAdapter{
|
||||
host: host,
|
||||
pluginID: "usage-detach",
|
||||
}
|
||||
|
||||
canceledCtx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
|
||||
adapter.HandleUsage(canceledCtx, coreusage.Record{
|
||||
Provider: "provider",
|
||||
Model: "gpt-5.4",
|
||||
})
|
||||
if receivedCtx == nil {
|
||||
t.Fatal("plugin did not receive context")
|
||||
}
|
||||
if errCtx := receivedCtx.Err(); errCtx != nil {
|
||||
t.Fatalf("expected detached context without error, got ctx.Err() = %v", errCtx)
|
||||
}
|
||||
|
||||
receivedCtx = nil
|
||||
adapter.HandleUsage(nil, coreusage.Record{
|
||||
Provider: "provider",
|
||||
Model: "gpt-5.4",
|
||||
})
|
||||
if receivedCtx == nil {
|
||||
t.Fatal("plugin did not receive context for nil input")
|
||||
}
|
||||
if errCtx := receivedCtx.Err(); errCtx != nil {
|
||||
t.Fatalf("expected non-nil context without error for nil input, got ctx.Err() = %v", errCtx)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUsageManagerRegisterNamedReplacesWithoutDuplicateDispatch(t *testing.T) {
|
||||
manager := coreusage.NewManager(0)
|
||||
defer manager.Stop()
|
||||
|
||||
@@ -136,6 +136,11 @@ func (a *usageAdapter) HandleUsage(ctx context.Context, record coreusage.Record)
|
||||
if plugin == nil {
|
||||
return
|
||||
}
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
} else {
|
||||
ctx = context.WithoutCancel(ctx)
|
||||
}
|
||||
defer func() {
|
||||
if recovered := recover(); recovered != nil {
|
||||
a.host.fusePlugin(a.pluginID, "UsagePlugin.HandleUsage", recovered)
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
"github.com/router-for-me/CLIProxyAPI/v7/sdk/pluginabi"
|
||||
"github.com/router-for-me/CLIProxyAPI/v7/sdk/pluginapi"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type rpcPluginAdapter struct {
|
||||
@@ -539,7 +540,9 @@ func (a rpcThinkingApplier) ApplyThinking(ctx context.Context, req pluginapi.Thi
|
||||
}
|
||||
|
||||
func (a *rpcPluginAdapter) HandleUsage(ctx context.Context, record pluginapi.UsageRecord) {
|
||||
_, _ = callPlugin[rpcEmptyResponse](ctx, a.client, pluginabi.MethodUsageHandle, record)
|
||||
if _, errCall := callPlugin[rpcEmptyResponse](ctx, a.client, pluginabi.MethodUsageHandle, record); errCall != nil {
|
||||
log.Debugf("pluginhost: usage.handle to %s failed: %v", a.id, errCall)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *rpcPluginAdapter) RegisterCommandLine(ctx context.Context, req pluginapi.CommandLineRegistrationRequest) (pluginapi.CommandLineRegistrationResponse, error) {
|
||||
|
||||
Reference in New Issue
Block a user