Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

122 lines
3.6 KiB
Go

package implementationhost
import (
"sort"
"sync"
"sync/atomic"
market "github.com/tutti-os/tutti/packages/connector/daemon/core"
connectorruntime "github.com/tutti-os/tutti/packages/connector/runtime"
connectorartifact "github.com/tutti-os/tutti/packages/connector/runtime/artifact"
)
type RouteRegistry struct {
mu sync.RWMutex
routes *connectorruntime.RouteTable
revision atomic.Uint64
}
type RouteDescriptor struct {
ConnectionID string
ConnectorKey string
ConnectorVersion string
ReleaseDigest string
Generation market.HostGeneration
DisplayName string
Description string
RoutingAliases []string
SkillRoot string
Skills []connectorartifact.SkillSummary
HasMCP bool
CLICommand string
CLIInvocationCommand string
CLIContractHash string
CLICommands []market.CLICommand
Readiness market.RuntimeReadiness
}
func (descriptor RouteDescriptor) InterfaceState(kind string) market.RuntimeReadinessState {
for _, readiness := range descriptor.Readiness.Interfaces {
if readiness.Kind == kind {
return readiness.State
}
}
return market.RuntimeReadinessFailed
}
func NewRouteRegistry() *RouteRegistry { return &RouteRegistry{} }
func (registry *RouteRegistry) Revision() uint64 {
if registry == nil {
return 0
}
return registry.revision.Load()
}
func (registry *RouteRegistry) notifyChanged() {
if registry != nil {
registry.revision.Add(1)
}
}
func (registry *RouteRegistry) attach(routes *connectorruntime.RouteTable) {
registry.mu.Lock()
registry.routes = routes
registry.mu.Unlock()
}
func (registry *RouteRegistry) activeRoutes() []*connectorRoute {
registry.mu.RLock()
table := registry.routes
registry.mu.RUnlock()
if table == nil {
return nil
}
portable := table.PublishedRoutes()
routes := make([]*connectorRoute, 0, len(portable))
for _, candidate := range portable {
if route, ok := candidate.(*connectorRoute); ok {
routes = append(routes, route)
}
}
return routes
}
func (registry *RouteRegistry) Routes() []RouteDescriptor {
routes := registry.activeRoutes()
result := make([]RouteDescriptor, 0, len(routes))
for _, route := range routes {
result = append(result, routeDescriptor(route))
}
sort.Slice(result, func(left, right int) bool {
if result[left].ConnectorKey != result[right].ConnectorKey {
return result[left].ConnectorKey < result[right].ConnectorKey
}
return result[left].ConnectionID < result[right].ConnectionID
})
return result
}
func routeDescriptor(route *connectorRoute) RouteDescriptor {
return RouteDescriptor{ConnectionID: route.connectionID, ConnectorKey: route.connectorKey,
ConnectorVersion: route.connectorVersion, ReleaseDigest: route.releaseDigest, Generation: route.generation,
DisplayName: route.displayName,
Description: route.description, RoutingAliases: append([]string(nil), route.routingAliases...),
SkillRoot: route.skillRoot, Skills: append([]connectorartifact.SkillSummary(nil), route.skills...),
HasMCP: len(route.mcpTools) > 0, CLICommand: route.cliCommand, CLIInvocationCommand: route.cliInvocationCommand,
CLIContractHash: route.cliContractHash,
CLICommands: cloneCLICommands(route.cliCommands),
Readiness: cloneRuntimeReadiness(route.readiness)}
}
func cloneCLICommands(commands []market.CLICommand) []market.CLICommand {
result := make([]market.CLICommand, 0, len(commands))
for _, command := range commands {
cloned := command
cloned.Arguments = append([]string(nil), command.Arguments...)
cloned.InputSchema = cloneJSONMap(command.InputSchema)
result = append(result, cloned)
}
return result
}