fix: resolve lint errors from upstream merge
- Remove unused activeRequests field, selectCandidates, findNearestUserMessage, and buildCommandsRuntime from loop.go - Remove duplicate createHTTPClient (moved to pkg/utils by upstream) - Fix golines violation (long line in helpers.go) - Fix misspell: serialises -> serializes - Fix golines: wrap long json.RawMessage literal in test Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
dbd9599913
commit
c65d45dae3
5 changed files with 6 additions and 144 deletions
|
|
@ -295,7 +295,8 @@ func setupAndStartServices(
|
|||
if strings.HasPrefix(webAppURL, "https://") {
|
||||
hostname, tsErr := tailscale.DetectHostname()
|
||||
if tsErr != nil {
|
||||
logger.ErrorCF("miniapp", "HTTPS URL configured but Tailscale not available", map[string]any{"error": tsErr.Error()})
|
||||
logger.ErrorCF("miniapp", "HTTPS URL configured but Tailscale not available",
|
||||
map[string]any{"error": tsErr.Error()})
|
||||
} else {
|
||||
certDir := filepath.Join(cfg.WorkspacePath(), "state", "certs")
|
||||
certFile, keyFile, certErr := tailscale.FetchCert(hostname, certDir)
|
||||
|
|
|
|||
|
|
@ -66,8 +66,6 @@ type AgentLoop struct {
|
|||
mcp mcpRuntime
|
||||
|
||||
mu sync.RWMutex
|
||||
// Track active requests for safe provider cleanup
|
||||
activeRequests sync.WaitGroup
|
||||
|
||||
providerCache map[string]providers.LLMProvider
|
||||
|
||||
|
|
@ -2263,69 +2261,6 @@ func (al *AgentLoop) runLLMIteration(
|
|||
return finalContent, iteration, nil
|
||||
}
|
||||
|
||||
// selectCandidates returns the model candidates and resolved model name to use
|
||||
// for a conversation turn. When model routing is configured and the incoming
|
||||
// message scores below the complexity threshold, it returns the light model
|
||||
// candidates instead of the primary ones.
|
||||
//
|
||||
// The returned (candidates, model) pair is used for all LLM calls within one
|
||||
// turn — tool follow-up iterations use the same tier as the initial call so
|
||||
// that a multi-step tool chain doesn't switch models mid-way.
|
||||
func (al *AgentLoop) selectCandidates(
|
||||
agent *AgentInstance,
|
||||
userMsg string,
|
||||
history []providers.Message,
|
||||
) (candidates []providers.FallbackCandidate, model string) {
|
||||
if agent.Router == nil || len(agent.LightCandidates) == 0 {
|
||||
return agent.Candidates, agent.Model
|
||||
}
|
||||
|
||||
_, usedLight, score := agent.Router.SelectModel(userMsg, history, agent.Model)
|
||||
if !usedLight {
|
||||
logger.DebugCF("agent", "Model routing: primary model selected",
|
||||
map[string]any{
|
||||
"agent_id": agent.ID,
|
||||
"score": score,
|
||||
"threshold": agent.Router.Threshold(),
|
||||
})
|
||||
return agent.Candidates, agent.Model
|
||||
}
|
||||
|
||||
logger.InfoCF("agent", "Model routing: light model selected",
|
||||
map[string]any{
|
||||
"agent_id": agent.ID,
|
||||
"light_model": agent.Router.LightModel(),
|
||||
"score": score,
|
||||
"threshold": agent.Router.Threshold(),
|
||||
})
|
||||
return agent.LightCandidates, agent.Router.LightModel()
|
||||
}
|
||||
|
||||
// findNearestUserMessage finds the nearest user message to the given index.
|
||||
// It searches backward first, then forward if no user message is found.
|
||||
func (al *AgentLoop) findNearestUserMessage(messages []providers.Message, mid int) int {
|
||||
originalMid := mid
|
||||
|
||||
for mid > 0 && messages[mid].Role != "user" {
|
||||
mid--
|
||||
}
|
||||
|
||||
if messages[mid].Role == "user" {
|
||||
return mid
|
||||
}
|
||||
|
||||
mid = originalMid
|
||||
for mid < len(messages) && messages[mid].Role != "user" {
|
||||
mid++
|
||||
}
|
||||
|
||||
if mid < len(messages) {
|
||||
return mid
|
||||
}
|
||||
|
||||
return originalMid
|
||||
}
|
||||
|
||||
// callLLMWithRetry calls the LLM with streaming support, fallback chain,
|
||||
// and retry logic for timeout and context window errors.
|
||||
func (al *AgentLoop) callLLMWithRetry(
|
||||
|
|
@ -2657,42 +2592,6 @@ func (al *AgentLoop) publishToolMedia(ctx context.Context, result *tools.ToolRes
|
|||
})
|
||||
}
|
||||
|
||||
func (al *AgentLoop) buildCommandsRuntime(agent *AgentInstance, opts *processOptions) *commands.Runtime {
|
||||
registry := al.GetRegistry()
|
||||
cfg := al.GetConfig()
|
||||
rt := &commands.Runtime{
|
||||
Config: cfg,
|
||||
ListAgentIDs: registry.ListAgentIDs,
|
||||
ListDefinitions: al.cmdRegistry.Definitions,
|
||||
GetEnabledChannels: func() []string {
|
||||
if al.channelManager == nil {
|
||||
return nil
|
||||
}
|
||||
return al.channelManager.GetEnabledChannels()
|
||||
},
|
||||
SwitchChannel: func(value string) error {
|
||||
if al.channelManager == nil {
|
||||
return fmt.Errorf("channel manager not initialized")
|
||||
}
|
||||
if _, exists := al.channelManager.GetChannel(value); !exists && value != "cli" {
|
||||
return fmt.Errorf("channel '%s' not found or not enabled", value)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
if agent != nil {
|
||||
rt.GetModelInfo = func() (string, string) {
|
||||
return agent.Model, cfg.Agents.Defaults.Provider
|
||||
}
|
||||
rt.SwitchModel = func(value string) (string, error) {
|
||||
oldModel := agent.Model
|
||||
agent.Model = value
|
||||
return oldModel, nil
|
||||
}
|
||||
}
|
||||
return rt
|
||||
}
|
||||
|
||||
// forceTextResponse makes a final LLM call without tools when max iterations
|
||||
// are exhausted, forcing a text response.
|
||||
func (al *AgentLoop) forceTextResponse(ctx context.Context, agent *AgentInstance, messages []providers.Message) string {
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ func buildRequestBody(
|
|||
func buildTools(tools []ToolDefinition) []any {
|
||||
result := make([]any, len(tools))
|
||||
for i, tool := range tools {
|
||||
// Unmarshal Parameters (json.RawMessage) into map so it serialises
|
||||
// Unmarshal Parameters (json.RawMessage) into map so it serializes
|
||||
// correctly as a nested JSON object rather than a raw byte string.
|
||||
var schema any
|
||||
if len(tool.Function.Parameters) > 0 {
|
||||
|
|
|
|||
|
|
@ -137,7 +137,9 @@ func TestBuildRequestBody(t *testing.T) {
|
|||
Function: ToolFunctionDefinition{
|
||||
Name: "get_weather",
|
||||
Description: "Get current weather",
|
||||
Parameters: json.RawMessage(`{"type":"object","properties":{"location":{"type":"string","description":"City name"}}}`),
|
||||
Parameters: json.RawMessage(
|
||||
`{"type":"object","properties":{"location":{"type":"string","description":"City name"}}}`,
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -89,46 +89,6 @@ func (it *APIKeyIterator) Next() (string, bool) {
|
|||
return key, true
|
||||
}
|
||||
|
||||
// createHTTPClient creates an HTTP client with optional proxy support
|
||||
func createHTTPClient(proxyURL string, timeout time.Duration) (*http.Client, error) {
|
||||
client := &http.Client{
|
||||
Timeout: timeout,
|
||||
Transport: &http.Transport{
|
||||
MaxIdleConns: 10,
|
||||
|
||||
IdleConnTimeout: 30 * time.Second,
|
||||
|
||||
DisableCompression: false,
|
||||
|
||||
TLSHandshakeTimeout: 15 * time.Second,
|
||||
},
|
||||
}
|
||||
|
||||
if proxyURL != "" {
|
||||
proxy, err := url.Parse(proxyURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid proxy URL: %w", err)
|
||||
}
|
||||
scheme := strings.ToLower(proxy.Scheme)
|
||||
switch scheme {
|
||||
case "http", "https", "socks5", "socks5h":
|
||||
default:
|
||||
return nil, fmt.Errorf(
|
||||
"unsupported proxy scheme %q (supported: http, https, socks5, socks5h)",
|
||||
proxy.Scheme,
|
||||
)
|
||||
}
|
||||
if proxy.Host == "" {
|
||||
return nil, fmt.Errorf("invalid proxy URL: missing host")
|
||||
}
|
||||
client.Transport.(*http.Transport).Proxy = http.ProxyURL(proxy)
|
||||
} else {
|
||||
client.Transport.(*http.Transport).Proxy = http.ProxyFromEnvironment
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
type SearchProvider interface {
|
||||
Search(ctx context.Context, query string, count int) (string, error)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue