139 lines · 5.3 KB · Go
RawDownload
package pluginhost import (	"context"	"fmt"	"strings" 	coreauth "github.com/router-for-me/CLIProxyAPI/v7/sdk/cliproxy/auth"	coreexecutor "github.com/router-for-me/CLIProxyAPI/v7/sdk/cliproxy/executor"	"github.com/router-for-me/CLIProxyAPI/v7/sdk/pluginapi"	sdktranslator "github.com/router-for-me/CLIProxyAPI/v7/sdk/translator") // executorPluginReady reports whether the named plugin can actually execute a// request right now: it must declare an executor capability AND resolve a// non-empty provider identifier (the same requirement enforced by// executorAdapterForPlugin at execution time), allow static execution without// selected auth, and declare formats compatible with the current request.// Routing pre-checks use this so that targets which would fail at execution are// treated as unhandled and fall through to lower-priority routers instead of// returning handled then 500ing.func (h *Host) executorPluginReady(pluginID string, routeReq pluginapi.ModelRouteRequest) bool {	if h == nil {		return false	}	pluginID = strings.TrimSpace(pluginID)	if pluginID == "" {		return false	}	for _, record := range h.activeRecords() {		if record.id != pluginID || h.isPluginFused(record.id) {			continue		}		executor := record.plugin.Capabilities.Executor		if executor == nil {			return false		}		if !executorScopeAllowsStaticModels(record.plugin.Capabilities) {			return false		}		provider, okProvider := h.executorProvider(record, executor)		if !okProvider {			return false		}		adapter := newExecutorAdapterRegistration(h, record, provider, executor).adapter		return adapter.supportsExecutorFormats(			coreexecutor.Request{Model: routeReq.RequestedModel, Payload: routeReq.Body},			coreexecutor.Options{				Stream:          routeReq.Stream,				OriginalRequest: routeReq.Body,				SourceFormat:    sdktranslator.FromString(routeReq.SourceFormat),				ResponseFormat:  sdktranslator.FromString(routeReq.SourceFormat),				Headers:         cloneHeader(routeReq.Headers),				Query:           cloneValues(routeReq.Query),				Metadata:        cloneInterceptorMetadata(routeReq.Metadata),			},		)	}	return false} func (a *executorAdapter) supportsExecutorFormats(req coreexecutor.Request, opts coreexecutor.Options) bool {	if a == nil {		return false	}	inputRequested := executorInputFormat(req, opts)	requestedFormat := executorRequestedFormat(req, opts)	inputFormat, errInput := a.selectExecutorInputFormat(inputRequested)	if errInput != nil {		return false	}	_, errOutput := a.selectExecutorOutputFormat(requestedFormat, inputFormat)	return errOutput == nil} // PluginExecutorRequestToFormat reports the executor input format selected for a direct plugin executor route.func (h *Host) PluginExecutorRequestToFormat(pluginID string, req coreexecutor.Request, opts coreexecutor.Options) sdktranslator.Format {	adapter, errAdapter := h.executorAdapterForPlugin(pluginID)	if errAdapter != nil {		return ""	}	return adapter.RequestToFormat(req, opts)} // ExecutePluginExecutor executes a request with the named plugin executor without changing the requested model.func (h *Host) ExecutePluginExecutor(ctx context.Context, pluginID string, req coreexecutor.Request, opts coreexecutor.Options) (coreexecutor.Response, error) {	adapter, errAdapter := h.executorAdapterForPlugin(pluginID)	if errAdapter != nil {		return coreexecutor.Response{}, errAdapter	}	return adapter.Execute(ctx, (*coreauth.Auth)(nil), req, opts)} // ExecutePluginExecutorStream executes a streaming request with the named plugin executor without changing the requested model.func (h *Host) ExecutePluginExecutorStream(ctx context.Context, pluginID string, req coreexecutor.Request, opts coreexecutor.Options) (*coreexecutor.StreamResult, error) {	adapter, errAdapter := h.executorAdapterForPlugin(pluginID)	if errAdapter != nil {		return nil, errAdapter	}	return adapter.ExecuteStream(ctx, (*coreauth.Auth)(nil), req, opts)} // CountPluginExecutor executes a count-tokens request with the named plugin executor without changing the requested model.func (h *Host) CountPluginExecutor(ctx context.Context, pluginID string, req coreexecutor.Request, opts coreexecutor.Options) (coreexecutor.Response, error) {	adapter, errAdapter := h.executorAdapterForPlugin(pluginID)	if errAdapter != nil {		return coreexecutor.Response{}, errAdapter	}	return adapter.CountTokens(ctx, (*coreauth.Auth)(nil), req, opts)} func (h *Host) executorAdapterForPlugin(pluginID string) (*executorAdapter, error) {	if h == nil {		return nil, fmt.Errorf("plugin host is unavailable")	}	pluginID = strings.TrimSpace(pluginID)	if pluginID == "" {		return nil, fmt.Errorf("target executor plugin id is required")	}	for _, record := range h.activeRecords() {		if record.id != pluginID {			continue		}		if h.isPluginFused(record.id) {			return nil, fmt.Errorf("plugin executor %s is unavailable", pluginID)		}		executor := record.plugin.Capabilities.Executor		if executor == nil {			return nil, fmt.Errorf("plugin %s does not declare an executor", pluginID)		}		provider, okProvider := h.executorProvider(record, executor)		if !okProvider {			return nil, fmt.Errorf("plugin executor %s has no provider identifier", pluginID)		}		registration := newExecutorAdapterRegistration(h, record, provider, executor)		return registration.adapter, nil	}	return nil, fmt.Errorf("plugin executor %s not found", pluginID)}