package cli_api import ( "context" "fmt" "net" "os" "strings" "github.com/mudler/LocalAI/core/p2p" "github.com/mudler/edgevpn/pkg/node" "github.com/rs/zerolog/log" ) func StartP2PStack(ctx context.Context, address, token, networkID string, federated bool) error { var n *node.Node // Here we are avoiding creating multiple nodes: // - if the federated mode is enabled, we create a federated node and expose a service // - exposing a service creates a node with specific options, and we don't want to create another node // If the federated mode is enabled, we expose a service to the local instance running // at r.Address if federated { _, port, err := net.SplitHostPort(address) if err != nil { return err } // Here a new node is created and started // and a service is exposed by the node node, err := p2p.ExposeService(ctx, "localhost", port, token, p2p.NetworkID(networkID, p2p.FederatedID)) if err != nil { return err } if err := p2p.ServiceDiscoverer(ctx, node, token, p2p.NetworkID(networkID, p2p.FederatedID), nil, false); err != nil { return err } n = node } // If the p2p mode is enabled, we start the service discovery if token != "" { // If a node wasn't created previously, create it if n == nil { node, err := p2p.NewNode(token) if err != nil { return err } err = node.Start(ctx) if err != nil { return fmt.Errorf("starting new node: %w", err) } n = node } // Attach a ServiceDiscoverer to the p2p node log.Info().Msg("Starting P2P server discovery...") if err := p2p.ServiceDiscoverer(ctx, n, token, p2p.NetworkID(networkID, p2p.WorkerID), func(serviceID string, node p2p.NodeData) { var tunnelAddresses []string for _, v := range p2p.GetAvailableNodes(p2p.NetworkID(networkID, p2p.WorkerID)) { if v.IsOnline() { tunnelAddresses = append(tunnelAddresses, v.TunnelAddress) } else { log.Info().Msgf("Node %s is offline", v.ID) } } tunnelEnvVar := strings.Join(tunnelAddresses, ",") os.Setenv("LLAMACPP_GRPC_SERVERS", tunnelEnvVar) log.Debug().Msgf("setting LLAMACPP_GRPC_SERVERS to %s", tunnelEnvVar) }, true); err != nil { return err } } return nil }