Files
zeekayandGitHub 5b5cf9e9db feat: merge AgentField control plane + SDKs as Hanzo Agents (#1)
Transforms hanzoai/agents from a marketplace config repo into a full
agent orchestration platform by merging the AgentField infrastructure:

- Go control plane (K8s-like agent orchestration, service mesh, DAG workflows)
- Python SDK (FastAPI-based agent framework, LiteLLM, memory, DID/VC)
- TypeScript SDK (@hanzo/agents - Vercel AI SDK, MCP, workflows)
- Go SDK (idiomatic agent builder + client)
- React 19 embedded dashboard (XyFlow DAGs, Recharts, Radix UI)
- Docker/K8s/Helm deployment configs
- Examples: hello world, deep research, RAG, simulation, benchmarks
- Functional test suite across Python/Go/TypeScript

All references rebranded: AgentField → Hanzo Agents
- Module: github.com/hanzoai/agents/control-plane
- Python: hanzo_agents
- TypeScript: @hanzo/agents
- Go: github.com/hanzoai/agents/sdk/go
- Env vars: HANZO_AGENTS_*
- Config: hanzo-agents.yaml

Previous marketplace configs moved to config/ directory.
2026-02-09 18:53:09 -08:00

76 lines
2.7 KiB
Go

// hanzo-agents/internal/infrastructure/process/port_manager.go
package process
import (
"fmt"
"net"
"github.com/hanzoai/agents/control-plane/internal/core/interfaces"
)
// DefaultPortManager provides a default implementation for managing network ports.
// It keeps track of reserved ports in memory.
type DefaultPortManager struct {
reservedPorts map[int]bool
}
// NewPortManager creates a new instance of DefaultPortManager.
// It initializes the map for tracking reserved ports.
func NewPortManager() interfaces.PortManager {
return &DefaultPortManager{
reservedPorts: make(map[int]bool),
}
}
// FindFreePort searches for an available port within a specific range (startPort to startPort+100).
// It checks both system availability and internal reservations.
// Returns the first free port found, or an error if no port is available in the range.
func (pm *DefaultPortManager) FindFreePort(startPort int) (int, error) {
// The search range is typically small, e.g., 100 ports.
// This can be made configurable if needed.
for port := startPort; port <= startPort+100; port++ {
if pm.IsPortAvailable(port) && !pm.reservedPorts[port] {
return port, nil
}
}
return 0, fmt.Errorf("no free port available in range %d-%d", startPort, startPort+100)
}
// IsPortAvailable checks if a specific port can be listened on.
// Returns true if the port is available (can be opened for listening), false otherwise.
func (pm *DefaultPortManager) IsPortAvailable(port int) bool {
address := fmt.Sprintf(":%d", port)
listener, err := net.Listen("tcp", address)
if err != nil {
return false // Port is likely in use or not permissible to use
}
// If listening was successful, close the listener immediately as we only wanted to check.
listener.Close()
return true
}
// ReservePort marks a port as reserved within this PortManager instance.
// It first checks if the port is system-available before reserving.
// Returns an error if the port is not available or cannot be reserved.
func (pm *DefaultPortManager) ReservePort(port int) error {
if !pm.IsPortAvailable(port) {
return fmt.Errorf("port %d is not available at the system level", port)
}
if pm.reservedPorts[port] {
return fmt.Errorf("port %d is already reserved by this manager", port)
}
pm.reservedPorts[port] = true
return nil
}
// ReleasePort removes a port from the internal reservation list.
// This makes the port available for future reservations by this manager.
// It does not affect the system-level availability of the port.
func (pm *DefaultPortManager) ReleasePort(port int) error {
if _, ok := pm.reservedPorts[port]; !ok {
return fmt.Errorf("port %d was not reserved by this manager", port)
}
delete(pm.reservedPorts, port)
return nil
}