🔴 unaiverse.utils.misc
What this module does 🔴
Grab-bag of utility helpers: node-address file IO, ID building, countdowns, JSON readiness checks, in-memory agent loading/packing, app dir prep, policies and a code analyzer.
misc
¶
█████ █████ ██████ █████ █████ █████ █████ ██████████ ███████████ █████████ ██████████
░░███ ░░███ ░░██████ ░░███ ░░███ ░░███ ░░███ ░░███░░░░░█░░███░░░░░███ ███░░░░░███░░███░░░░░█
░███ ░███ ░███░███ ░███ ██████ ░███ ░███ ░███ ░███ █ ░ ░███ ░███ ░███ ░░░ ░███ █ ░
░███ ░███ ░███░░███░███ ░░░░░███ ░███ ░███ ░███ ░██████ ░██████████ ░░█████████ ░██████
░███ ░███ ░███ ░░██████ ███████ ░███ ░░███ ███ ░███░░█ ░███░░░░░███ ░░░░░░░░███ ░███░░█
░███ ░███ ░███ ░░█████ ███░░███ ░███ ░░░█████░ ░███ ░ █ ░███ ░███ ███ ░███ ░███ ░ █
░░████████ █████ ░░█████░░████████ █████ ░░███ ██████████ █████ █████░░█████████ ██████████
░░░░░░░░ ░░░░░ ░░░░░ ░░░░░░░░ ░░░░░ ░░░ ░░░░░░░░░░ ░░░░░ ░░░░░ ░░░░░░░░░ ░░░░░░░░░░
A Collectionless AI Project (https://collectionless.ai)
Registration/Login: https://unaiverse.io
Code Repositories: https://github.com/collectionlessai/
Main Developers: Stefano Melacci (Project Leader), Christian Di Maio, Tommaso Guidi
Silent
¶
Context manager that suppresses stdout by redirecting it to /dev/null.
On entry, sys.stdout is replaced with a handle to /dev/null so that any
print or other stdout writes are silently discarded. On exit, the original
sys.stdout is restored regardless of whether an exception occurred.
If ignore=True is passed to the constructor, the context manager becomes a
no-op and stdout is left unchanged. This is useful when callers want to toggle
suppression without restructuring control flow.
Initialize the Silent context manager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ignore
|
bool
|
If |
False
|
Source code in unaiverse/utils/misc.py
FileTracker
¶
Monitor a folder for file creation, modification, and deletion events.
FileTracker works by comparing nanosecond-precision modification timestamps
(st_mtime_ns) between successive calls to something_changed. Only files
that match the configured extension, optional prefix, and optional skip-name filter
are considered.
The initial snapshot is taken at construction time, so the first call to
something_changed reflects changes that occurred after the object was created.
Attributes:
| Name | Type | Description |
|---|---|---|
folder |
|
|
ext |
Lowercase file extension that is tracked (e.g. |
|
skip |
Exact file name to exclude from tracking, or |
|
prefix |
File-name prefix filter, or |
|
last_state |
Most recent snapshot dict mapping file names to |
Initialize the FileTracker and take an initial snapshot of the folder.
The snapshot records the st_mtime_ns of every file in folder that
satisfies all active filters. Subsequent calls to something_changed compare
against this baseline.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
folder
|
str
|
Path to the folder to monitor. |
required |
ext
|
str
|
File extension (including the leading dot) to watch. The comparison is
case-insensitive. Defaults to |
'.json'
|
prefix
|
str | None
|
If set, only files whose names start with this string are tracked.
Defaults to |
None
|
skip
|
str | None
|
If set, the file with this exact name is excluded from tracking.
Defaults to |
None
|
Source code in unaiverse/utils/misc.py
something_changed
¶
Check whether any tracked file has been created, modified, or deleted since the last call.
A new folder snapshot is taken on every invocation and compared against
last_state. Changes are detected in three categories: new files that did not
exist in the previous snapshot (created), files whose st_mtime_ns differs
(modified), and files that were present before but are gone now (deleted).
last_state is updated to the new snapshot regardless of whether a change was
detected.
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
|
Source code in unaiverse/utils/misc.py
InMemoryFinder
¶
Bases: MetaPathFinder
MetaPathFinder that resolves imports from an in-memory source dict.
Each instance owns a unique namespace (e.g. _dyn_abc12345) so that
concurrent worlds loaded by different agents never collide in sys.modules.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
py_files
|
dict[str, str]
|
Dict mapping relative paths (forward-slash, e.g.
|
required |
namespace
|
str
|
Unique string used as the top-level package name. |
required |
Source code in unaiverse/utils/misc.py
find_spec
¶
Source code in unaiverse/utils/misc.py
cleanup
¶
Remove all owned modules from "sys.modules" and unregister this finder.
Call this when the agent that was built from these sources is destroyed.
Source code in unaiverse/utils/misc.py
PolicyFilterDelayAction
¶
Policy filter that delays self-generation or learning actions by a configurable wait time.
Initialises the PolicyFilterSelfGen.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
action_names
|
set[str]
|
The name of the actions to delay (set). |
required |
wait
|
float
|
Minimum number of seconds to wait before allowing |
required |
add_random_up_to
|
float
|
Upper bound of an additional random delay in seconds
added to |
0.0
|
Raises:
| Type | Description |
|---|---|
GenException
|
If |
Source code in unaiverse/utils/misc.py
PolicyHumanLikeDelay
¶
Policy filter that delays actions with human-like variable timing.
Uses a log-normal distribution (which naturally models human reaction times) combined with momentum (bursts of fast/slow behavior) and occasional distraction spikes. All internal dynamics are derived from the three constructor parameters.
Initialises the PolicyHumanLikeDelay.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
action_names
|
set[str]
|
The name of the actions to delay (set). |
required |
median_delay
|
float
|
Median delay in seconds (the "typical" human response time). |
5.0
|
variability
|
float
|
How spread out the delays are (0.0 = nearly constant, 1.0+ = very erratic). Values around 0.4-0.8 are realistic. Also controls momentum strength and distraction probability internally. |
0.6
|
Raises:
| Type | Description |
|---|---|
GenException
|
If |
Source code in unaiverse/utils/misc.py
MultiPartLimitedDict
¶
Bases: dict
A dict subclass that keeps at most a configurable number of entries per named partition.
Initialises the MultiPartLimitedDict.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
part_name_to_limit
|
dict
|
A dictionary mapping partition names to their maximum entry counts. |
required |
Source code in unaiverse/utils/misc.py
set_part
¶
Switches the active partition so that subsequent __setitem__ calls are attributed to it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
part_label
|
str
|
The name of the partition to activate. Unknown labels are silently ignored. |
required |
Source code in unaiverse/utils/misc.py
build_unaid
¶
Return the canonical UNaIVERSE agent identifier (UNAID) for a node profile.
Combines the node's email address and node name into a single slash-separated
string of the form "<email>/<node_name>". This identifier is used throughout
the framework as a stable, human-readable key for a specific agent instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
profile
|
A node profile object that exposes a |
required |
Returns:
| Type | Description |
|---|---|
|
A string of the form |
Source code in unaiverse/utils/misc.py
save_node_addresses_to_file
¶
save_node_addresses_to_file(node: object, dir_path: str, public: bool, filename: str = 'addresses.txt', append: bool = False) -> None
Write the hosted node's name and its public or world addresses to a file.
Each call writes exactly one line in the format "<node_name>;<address_list>",
where <address_list> is the string representation of the list returned by
get_public_addresses() or get_world_addresses(). The file is flushed
immediately after writing so that concurrent readers see fresh data.
This format is the counterpart to get_node_addresses_from_file, which parses
the same name;[addr, ...] structure.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
node
|
object
|
The node object whose addresses are to be saved. Expected to expose
|
required |
dir_path
|
str
|
Directory in which the output file is created or updated. |
required |
public
|
bool
|
If |
required |
filename
|
str
|
Name of the output file. Defaults to |
'addresses.txt'
|
append
|
bool
|
If |
False
|
Source code in unaiverse/utils/misc.py
get_node_addresses_from_file
¶
get_node_addresses_from_file(dir_path: str, filename: str = 'addresses.txt') -> dict[str, list[str]]
Read node names and their address lists from a file.
Supports two file formats:
- Legacy format: each non-empty line is a single address string starting with
"/". All addresses are collected under the key"unk". - Current format: each line is
"<node_name>;<python_list_literal>", where the list literal is evaluated withast.literal_eval. Lines starting with"***"are treated as header markers and skipped. If the same node name appears on multiple lines, only the last entry is kept.
The current format is produced by save_node_addresses_to_file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dir_path
|
str
|
Directory containing the file. |
required |
filename
|
str
|
Name of the file to read. Defaults to |
'addresses.txt'
|
Returns:
| Type | Description |
|---|---|
dict[str, list[str]]
|
A dict mapping node names to lists of address strings. Returns an empty dict if |
dict[str, list[str]]
|
the file exists but contains no non-empty lines. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If the file does not exist in |
ValueError
|
If |
Source code in unaiverse/utils/misc.py
countdown_start
¶
Start a tqdm progress-bar countdown in a background thread.
A non-daemon thread is created that displays a tqdm progress bar over
seconds ticks, sleeping one second between each tick. During the countdown,
sys.stdout inside the thread is redirected through a TqdmPrintRedirector
so that ordinary print calls are routed to tqdm.write and do not break
the bar layout. The original sys.stdout is restored when the countdown
completes.
The caller should eventually pass the returned handle to countdown_wait to
block until the countdown finishes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seconds
|
int
|
Total number of seconds to count down. |
required |
msg
|
str
|
Description label displayed to the left of the progress bar. |
required |
Returns:
| Type | Description |
|---|---|
Thread
|
A |
Thread
|
|
Source code in unaiverse/utils/misc.py
countdown_wait
¶
Block until the countdown thread created by countdown_start finishes.
Calls join() on the provided thread handle, suspending the caller until the
countdown completes. This is the intended companion to countdown_start.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
handle
|
Thread
|
The |
required |
Source code in unaiverse/utils/misc.py
check_json_start
¶
Start a background daemon thread that monitors a JSON file for changes and pretty-prints it.
The watcher loop polls the file every second. Whenever the parsed JSON content
differs from the previous snapshot, the current timestamp and the full JSON body
are rendered to the console via rich. Parse errors and other transient
exceptions are silently ignored so that the watcher survives temporary write
conflicts.
Because the thread is a daemon, it is automatically stopped when the main program
exits. The caller may also pass the returned handle to check_json_start_wait
to block explicitly (though in practice the daemon loop runs until the process ends
or a KeyboardInterrupt is raised inside the thread).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file
|
str
|
Path to the JSON file to monitor. |
required |
msg
|
str
|
A header message printed once to stdout when monitoring begins. |
required |
delete_existing
|
bool
|
If |
False
|
Returns:
| Type | Description |
|---|---|
Thread
|
A daemon |
Thread
|
|
Source code in unaiverse/utils/misc.py
check_json_start_wait
¶
Block until the JSON-watcher thread created by check_json_start finishes.
Calls join() on the provided daemon thread handle. Because the watcher loop
runs indefinitely, this call will block until the process exits or the thread is
stopped externally.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
handle
|
Thread
|
The daemon |
required |
Source code in unaiverse/utils/misc.py
show_images_grid
¶
Display a grid of images from the given file paths using matplotlib.
The figure size is derived from the average pixel dimensions of the loaded images, scaled to a figure-coordinate unit of 100 pixels. Each image is shown without axes and labelled with its zero-based index. Unused grid cells are hidden.
Matplotlib interactive mode is enabled (plt.ion()) before displaying the
figure so that the call does not block the caller.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image_paths
|
list[str]
|
List of file-path strings pointing to the images to display.
All paths must be readable by |
required |
max_cols
|
int
|
Maximum number of columns in the image grid. The actual number of
columns is |
3
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in unaiverse/utils/misc.py
pack_py_files
¶
Serialize, gzip-compress, and base64-encode a py-files dict.
The dict is serialized to JSON, compressed with gzip, and then encoded as a
URL-safe-alphabet Base64 ASCII string. The result can be safely embedded in any
text-based message or protocol field.
The inverse operation is unpack_py_files.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
py_files
|
dict[str, str]
|
Dict mapping relative file paths (forward-slash separated) to Python
source text strings, as produced by |
required |
Returns:
| Type | Description |
|---|---|
str
|
A plain ASCII string containing the compressed, Base64-encoded representation |
str
|
of |
Source code in unaiverse/utils/misc.py
collect_py_files
¶
Collect all .py sources under folder, skipping named subdirectories.
Walks the directory tree recursively using Path.rglob. Any file whose path
contains a component (other than the filename itself) that appears in
exclude_dirs is skipped. Back-slashes in relative paths are normalised to
forward slashes so the result is consistent across operating systems.
The output dict is the canonical input format for pack_py_files and
InMemoryFinder.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
folder
|
str
|
Root directory to walk. |
required |
exclude_dirs
|
set[str] | None
|
Set of sub-directory names to skip entirely. Files directly
under |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
A dict mapping each file's path relative to |
dict[str, str]
|
separated, e.g. |
dict[str, str]
|
source text. |
Source code in unaiverse/utils/misc.py
unpack_py_files
¶
Base64-decode, decompress, and deserialize a packed py-files string.
Reverses the three-step transformation applied by pack_py_files: Base64
decoding, gzip decompression, and JSON deserialization.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
packed
|
str
|
A Base64-encoded, gzip-compressed string produced by |
required |
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
The original dict mapping relative file paths (forward-slash separated) to |
dict[str, str]
|
Python source text strings. |
Raises:
| Type | Description |
|---|---|
Exception
|
Any exception raised by |
Source code in unaiverse/utils/misc.py
load_agent_in_memory
¶
load_agent_in_memory(py_files: dict[str, str], role: str, **init_kwargs: Any) -> tuple[Any, InMemoryFinder]
Instantiate a WAgent from an in-memory Python source tree.
The file {role}.py (at the root of py_files) is imported as the
agent's main module. Any import statements inside it are resolved
against the other entries in py_files through a temporary
InMemoryFinder registered on sys.meta_path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
py_files
|
dict[str, str]
|
Dict mapping relative paths to source text (as produced by
|
required |
role
|
str
|
Role name; |
required |
**init_kwargs
|
Any
|
Keyword arguments forwarded to |
{}
|
Returns:
| Type | Description |
|---|---|
Any
|
A |
InMemoryFinder
|
finder alive as long as the agent is in use, and call |
tuple[Any, InMemoryFinder]
|
|
Raises:
| Type | Description |
|---|---|
KeyError
|
If |
Exception
|
Any exception raised during module execution or
|
Source code in unaiverse/utils/misc.py
prepare_app_dir
¶
Resolves and creates the platform-appropriate application data directory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
app_name
|
str
|
Name of the application subdirectory (default: |
'unaiverse'
|
Returns:
| Type | Description |
|---|---|
str
|
The absolute path to the created directory. |
Source code in unaiverse/utils/misc.py
get_key_considering_multiple_sources
¶
Retrieves the UNaIVERSE authentication key from one of several sources.
Checks, in priority order: (1) the key_variable argument, (2) the NODE_KEY
environment variable, and (3) a cached key file. If multiple sources are found,
a warning is printed. If no source is found, the user is prompted interactively and
the entered key is saved to the cache file for future use.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key_variable
|
str | None
|
A key string passed directly from code, or None (and placeholder
strings enclosed in |
required |
Returns:
| Type | Description |
|---|---|
str
|
The resolved authentication key string. |
Source code in unaiverse/utils/misc.py
689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 | |
analyze_code
¶
Analyzes a string of Python code for dangerous or unsafe functions and modules.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
files_in_memory
|
dict[str, str]
|
The dict "file name to code string with contents". |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if the code is considered safe, otherwise False. |