- base.go: merge base_ext.go back to match upstream layout (context helpers, AsyncExecutor in base.go; StatusProvider + ContextualTool + AsyncTool as fork-only additions) - registry.go: adopt upstream's ToolEntry struct with IsCore/TTL, hidden tools, RegisterHidden, PromoteTools, TickTTL, Version, SnapshotHiddenTools; merge ExecuteWithContext/ToProviderDefs/GetSummaries from registry_ext.go - registry_ext.go: reduced to fork-only GetRuntimeStatus + buildParamHint - config.go: add upstream-only types and fields (VoiceConfig, BuildInfo, ToolDiscoveryConfig, ReadFileToolConfig, MergeAPIKeys, MessageFormat, AllowRemote, APIKeys on search configs, Minimax/LongCat providers, UnmarshalText, QQ MaxMessageLength/SendMarkdown); merge SubagentsConfig and PeerMatch back from config_ext.go - Delete base_ext.go and config_ext.go (contents merged back) - Fix pre-existing anthropic provider build error (FunctionCall.Arguments is now map[string]any, not string) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
68 lines
1.5 KiB
Go
68 lines
1.5 KiB
Go
package tools
|
|
|
|
import (
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
// --- Fork-only registry extensions ---
|
|
|
|
// GetRuntimeStatus aggregates runtime status from all tools that implement StatusProvider.
|
|
// Returns empty string if no tool has status to report.
|
|
func (r *ToolRegistry) GetRuntimeStatus() string {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
|
|
var parts []string
|
|
for _, entry := range r.tools {
|
|
if sp, ok := entry.Tool.(StatusProvider); ok {
|
|
if s := sp.RuntimeStatus(); s != "" {
|
|
parts = append(parts, s)
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(parts) == 0 {
|
|
return ""
|
|
}
|
|
|
|
return strings.Join(parts, "\n\n")
|
|
}
|
|
|
|
// buildParamHint extracts parameter names from a JSON schema and returns
|
|
// a hint string like "(task, label?, preset?)". Required params are bare,
|
|
// optional params have a trailing "?".
|
|
func buildParamHint(schema map[string]any) string {
|
|
props, _ := schema["properties"].(map[string]any)
|
|
if len(props) == 0 {
|
|
return ""
|
|
}
|
|
|
|
reqSlice, _ := schema["required"].([]string)
|
|
reqSet := make(map[string]bool, len(reqSlice))
|
|
for _, r := range reqSlice {
|
|
reqSet[r] = true
|
|
}
|
|
|
|
names := make([]string, 0, len(props))
|
|
for name := range props {
|
|
names = append(names, name)
|
|
}
|
|
sort.Strings(names)
|
|
|
|
parts := make([]string, 0, len(names))
|
|
|
|
// Required params first, then optional
|
|
for _, name := range names {
|
|
if reqSet[name] {
|
|
parts = append(parts, name)
|
|
}
|
|
}
|
|
for _, name := range names {
|
|
if !reqSet[name] {
|
|
parts = append(parts, name+"?")
|
|
}
|
|
}
|
|
|
|
return "(" + strings.Join(parts, ", ") + ")"
|
|
}
|