Class AbstractAsiContainer
- All Implemented Interfaces:
PropertyChangeSource, Rebindable
- Direct Known Subclasses:
AbstractSwingAsiContainer
- Static methods provide access to the root Anahata AI working directory and its global subdirectories.
- An instance of this class represents the configuration for a specific host application (e.g., "netbeans", "standalone"), managing its unique preferences and its own application-specific subdirectories.
- Author:
- anahata-gemini-pro-2.5
-
Field Summary
FieldsModifier and TypeFieldDescriptionThe list of currently active agi sessions managed by this container.static MapA JVM-scoped map for tools to store and share objects across all containers, sessions, and turns.A container-scoped map for tools to store objects across all sessions and turns within this specific host application.private final ExecutorServiceA shared executor for container-level background tasks.private final StringThe unique identifier for the host application (e.g., "netbeans", "standalone").private booleanFlag controlling the execution loop of the background key file watcher daemon thread.private ThreadDedicated daemon thread polling provider API key files on disk.Container-level operational notifications and boot diagnostic records.private final Map<String, AbstractAiProvider> A master registry of AI provider instances.private final Map<String, PropertyChangeListener> Map tracking active property change listeners per session to allow clean detaching on unregistration.The list of reusable AGI session templates managed by this container.Fields inherited from class BasicPropertyChangeSource
propertyChangeSupport -
Constructor Summary
ConstructorsConstructorDescriptionAbstractAsiContainer(String hostApplicationId) Creates a configuration instance for a specific host application. -
Method Summary
Modifier and TypeMethodDescriptionvoidaddNotification(String notification) Adds an operational notification or startup diagnostic message.voidautoSaveSession(Agi agi, String reason) Performs an automatic backup of the session using Kryo serialization.voidClears all recorded operational notifications.Authoritatively clones an existing Agi session or template with an auto-generated UUID.Authoritatively clones an existing Agi session or template.voidAuthoritatively requests that the specified agi session's UI tab or window be closed.protected voidconfigureNewAgi(Agi agi) Hook invoked to perform initial post-birth configuration of a new Agi.final AgiAuthoritatively creates, configures, registers, and opens a brand-new Agi session using the user's preferred template.final AgicreateNewAgi(AgiConfig config) Authoritatively creates, configures, registers, and opens a brand-new Agi session with the provided configuration.abstract AgiConfigCreates a new agi session blueprint.createNewAgiFromTemplate(String templateId) Authoritatively creates and opens a new active AGI session cloned directly from a template file on disk.createNewAgiFromTemplate(Agi templateAgi) Authoritatively creates and opens a new active AGI session cloned from a template instance.final AgiAuthoritatively creates, configures, registers, and opens a brand-new Agi session using the clean framework config, bypassing any default template.createTemplate(@NonNull String templateId) Creates, configures, and saves a fresh new template.createTemplateFromSession(@NonNull Agi sessionAgi, @NonNull String templateId) Creates and saves a new template cloned from an active AGI session, preserving its nickname.voidPermanently disposes of a agi session or template, shutting it down and moving its serialized file to the 'disposed' directory.static PathEnsures that a given directory exists on disk, creating it if missing.findModels(String query, List<ResponseModality> modalities, boolean enabledOnly) Finds and filters models across providers matching a regex/text query AND all requested response modalities.Gets an unmodifiable list of all active agi sessions.Retrieves an active Agi instance from the container pool by its unique UUID / session ID.getAllModels(boolean providerEnabled) Gets all loaded models across all providers from memory.getAllModels(boolean providerEnabled, boolean modelEnabled) Gets all loaded models across all providers from memory.Gets an unmodifiable list of all registered provider instances.getAppDirSubDir(String name) Gets a named subdirectory within this host application's working directory, creating it if it doesn't exist. e.g., ~/.anahata/asi/netbeans/sessionsstatic StringResolves the implementation version of the foundational Anahata ASI Core framework.getChildrenAgis(String parentUuid) Retrieves all active Agi sessions spawned by a specific parent.Retrieves the creation time of this container's directory from metadata or filesystem attributes.Resolves the implementation version of this specific host container artifact.Resolves the clean container version string used for the container directory.Finds the default template whose session ID is "default" (case-insensitive).Gets the root working directory for this specific host application instance. e.g., ~/.anahata/asi/netbeans or ~/.anahata/asi/netbeans/1.2.0Gets the directory where disposed agi sessions are moved.Gets an unmodifiable list of all registered AI providers that are effectively enabled (the provider is enabled and either does not require an API key or has valid keys configured).Resolves the Maven Artifact ID of this specific host container module.Resolves the Maven Group ID of this container artifact.Gets an unmodifiable copy of all recorded operational notifications.Gets an unmodifiable list of all agi sessions that are currently logically open in the host UI.getPersistenceDir(Agi agi) Gets the primary persistence directory for the given AGI session or template.getProvider(String uuid) Retrieves a shared provider instance from the master registry by its UUID.<T extends AbstractAiProvider>
TgetProviderByClass(Class<T> providerClass) Finds a registered provider instance of a specific class.Gets the directory where persisted AI provider entities are stored.Gets the directory where manually saved agi sessions are stored.getSessionResourcesUnderPath(@NonNull Path path) Resolves in-context resources under a given filesystem path across all open AGI sessions.Gets the directory where active agi sessions are stored.static PathgetSubdirectory(Path parent, String subdirName) Resolves a named subdirectory against a parent path, ensuring it exists on disk.Gets an unmodifiable list of all registered AGI templates.Gets the directory where AGI session templates are stored.abstract ObjectRetrieves the platform-specific UI component associated with an Agi session.Gets the directory where AI provider entities that failed to load are moved.Gets the directory where agi sessions that failed to load are moved.Gets the directory where AGI templates that failed to load are moved.static PathGets the root Anahata AI working directory (e.g., ~/.anahata/asi or $SNAP_USER_DATA/.anahata/asi).static PathgetWorkDirSubDir(String name) Gets a named subdirectory within the global root working directory, creating it if it doesn't exist.booleanChecks if any of the AI providers configured in the global template have at least one valid API key.importSession(Path path) Imports an Agi session from an external file.booleanisTemplate(@NonNull Agi agi) Checks if the given session is an AGI template managed by this container.Deserializes an Agi instance from a file, rebinds it to this container, and automatically moves it to the 'unloadable' subdirectory on failure.intScans a directory for .kryo files in parallel, deserializes each vialoadAgi(Path), and invokes the registration callback as each finishes loading.intScans the container's providers directory and loads all serialized AI provider entities.intScans the sessions directory and loads all serialized active Agi sessions.intScans the templates directory and loads all serialized AGI templates into memory.voidmanualSaveSession(Agi agi) Manually saves the session to the 'saved' directory, or to templates if template.protected abstract voidonAgiClosed(Agi agi) Hook invoked when a session has been logically closed.protected abstract voidonAgiOpened(Agi agi) Hook invoked when a session has been logically opened.voidonAgiRegistered(Agi agi) Hook invoked whenever a session enters the active pool.voidonAgiUnregistered(Agi agi) Hook invoked whenever a session is removed from the active pool.protected voidonSessionContextChanged(Agi agi, String propertyName) Hook invoked whenever an AGI session's context, resources, nickname, or visibility state changes, or when a session is unregistered.voidauthoritatively requests that the specified agi session be opened and brought to the front in the host UI.private voidregisterActiveAgi(Agi agi) Internal logic for session pooling and common hook invocation.voidregisterProvider(@NonNull AbstractAiProvider provider) Registers a new provider instance in the master registry, binds its container reference, and persists it directly to disk in the container's providers directory.voidregisterTemplate(@NonNull Agi templateAgi) Registers a template instance into the container's template registry and fires a property change event.voidSaves the AGI instance to its designated persistence directory.private voidSerializes and saves an Agi session to a specific directory using Kryo.voidshutdown()Shuts down the container, interrupts the key watcher thread, and terminates the shared executor.private voidStarts a dedicated low-priority daemon thread that polls API key files once per second.voidunregisterAgi(Agi agi) Unregisters a agi session from this configuration and triggers host-aware cleanup hooks.voidunregisterProvider(String uuid) Unregisters a provider instance, removing it from the registry and the persistent preferences.voidunregisterTemplate(Agi templateAgi) Unregisters a template from the container's template registry and fires a property change event.Methods inherited from class BasicPropertyChangeSource
addPropertyChangeListener, addPropertyChangeListener, rebind, removePropertyChangeListener, removePropertyChangeListenerMethods inherited from class Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface PropertyChangeSource
getPropertyChangeSupport
-
Field Details
-
sessionListeners
Map tracking active property change listeners per session to allow clean detaching on unregistration. -
hostApplicationId
The unique identifier for the host application (e.g., "netbeans", "standalone").Used to resolve application-specific subdirectories within the root Anahata working directory.
-
activeAgis
-
templates
-
providerRegistry
A master registry of AI provider instances.Keyed by the provider's unique UUID. These instances are shared across all sessions managed by this container.
-
executor
A shared executor for container-level background tasks. -
applicationAttributes
A JVM-scoped map for tools to store and share objects across all containers, sessions, and turns. This map is thread-safe. -
containerAttributes
A container-scoped map for tools to store objects across all sessions and turns within this specific host application. This map is thread-safe. -
notifications
-
keyWatcherRunning
private volatile boolean keyWatcherRunningFlag controlling the execution loop of the background key file watcher daemon thread. -
keyWatcherThread
Dedicated daemon thread polling provider API key files on disk.
-
-
Constructor Details
-
AbstractAsiContainer
Creates a configuration instance for a specific host application. Upon instantiation, it loads the preferences and persisted providers for that application.- Parameters:
hostApplicationId- A unique identifier for the host application (e.g., "netbeans").
-
-
Method Details
-
loadProvidersFromDisk
public int loadProvidersFromDisk()Scans the container's providers directory and loads all serialized AI provider entities.- Returns:
- The number of providers loaded from disk.
-
addNotification
Adds an operational notification or startup diagnostic message.- Parameters:
notification- The diagnostic message to record.
-
clearNotifications
public void clearNotifications()Clears all recorded operational notifications. -
getNotifications
-
getAllModels
Gets all loaded models across all providers from memory.- Parameters:
providerEnabled- if true, filters to only effectively enabled providers (enabled with valid API keys).modelEnabled- if true, filters to only enabled models (model.isEnabled()).- Returns:
- an aggregated list of matching models.
-
getAllModels
Gets all loaded models across all providers from memory.- Parameters:
providerEnabled- if true, filters to only effectively enabled providers.- Returns:
- an aggregated list of all models.
-
findModels
public List<AbstractModel> findModels(String query, List<ResponseModality> modalities, boolean enabledOnly) Finds and filters models across providers matching a regex/text query AND all requested response modalities.- Parameters:
query- Optional regex or keyword query.modalities- Optional list of response modalities (e.g. [IMAGE, AUDIO]).enabledOnly- If true, filters to only effectively enabled providers (enabled with valid API keys).- Returns:
- A list of matching
AbstractModelinstances across matching providers.
-
getProvider
Retrieves a shared provider instance from the master registry by its UUID.Implementation details: This is the authoritative way to resolve providers. If the UUID is
null, this method returnsnull.- Parameters:
uuid- The unique UUID of the provider instance.- Returns:
- The shared provider instance, or
nullif not found.
-
getAllProviders
Gets an unmodifiable list of all registered provider instances.- Returns:
- All providers sorted by priority and display name.
-
registerProvider
Registers a new provider instance in the master registry, binds its container reference, and persists it directly to disk in the container's providers directory.- Parameters:
provider- The provider instance to register.
-
unregisterProvider
Unregisters a provider instance, removing it from the registry and the persistent preferences.- Parameters:
uuid- The UUID of the provider to unregister.
-
getProviderByClass
Finds a registered provider instance of a specific class.- Type Parameters:
T- The provider type.- Parameters:
providerClass- The class to look for.- Returns:
- The first matching instance, or null if none registered.
-
getAsiCoreImplementationVersion
Resolves the implementation version of the foundational Anahata ASI Core framework.Extracts the version from the package manifest of
AbstractAsiContaineror from the Mavenpom.propertiespackaged into the Core artifact at build time.- Returns:
- The Core implementation version string, or
nullif running in an unpackaged test environment.
-
getMavenGroupId
Resolves the Maven Group ID of this container artifact.Defaults to
"uno.anahata". Development Notice: This method is used in development mode to locatepom.propertieson the classpath when running directly offtarget/classes.- Returns:
- The Maven groupId string.
-
getMavenArtifactId
Resolves the Maven Artifact ID of this specific host container module.Development Notice: Subclasses representing specific host environments (e.g.
anahata-asi-desktop,anahata-asi-nb) should override this method so thatgetContainerImplementationVersion()can fish the build version from/META-INF/maven/<groupId>/<artifactId>/pom.propertieswhen running directly offtarget/classesin development mode.- Returns:
- The Maven artifactId string, or
nullif unknown.
-
getContainerImplementationVersion
Resolves the implementation version of this specific host container artifact.Resolution Hierarchy:
- Queries
getClass().getPackage().getImplementationVersion()(active in packaged production JARs and NBMs). - In development mode (when running off
target/classes), fishes the version from/META-INF/maven/<getMavenGroupId()>/<getMavenArtifactId()>/pom.propertieson the classpath. - Falls back to
getAsiCoreImplementationVersion().
- Returns:
- The container implementation version string, or
nullif unresolved.
- Queries
-
getContainerVersion
Resolves the clean container version string used for the container directory.Discards any qualifiers or build timestamps after the first dash ('-'). For example, '1.2.0-20260904' or '1.2.0-SNAPSHOT' becomes '1.2.0'.
- Returns:
- The clean version string, or
nullif unresolved.
-
getDirectory
Gets the root working directory for this specific host application instance. e.g., ~/.anahata/asi/netbeans or ~/.anahata/asi/netbeans/1.2.0- Returns:
- The application-specific working directory path.
- Throws:
IOException- If creating the directory fails.
-
getContainerCreationTime
-
getProvidersDir
Gets the directory where persisted AI provider entities are stored.- Returns:
- The providers directory path.
- Throws:
IOException- If creating the directory fails.
-
getUnloadableProvidersDir
Gets the directory where AI provider entities that failed to load are moved.- Returns:
- The unloadable providers directory path.
- Throws:
IOException- If creating the directory fails.
-
getTemplatesDir
Gets the directory where AGI session templates are stored.- Returns:
- The templates directory path.
- Throws:
IOException- If creating the directory fails.
-
getUnloadableTemplatesDir
Gets the directory where AGI templates that failed to load are moved.- Returns:
- The unloadable templates directory path.
- Throws:
IOException- If creating the directory fails.
-
getAppDirSubDir
Gets a named subdirectory within this host application's working directory, creating it if it doesn't exist. e.g., ~/.anahata/asi/netbeans/sessions- Parameters:
name- The name of the subdirectory.- Returns:
- The Path to the application-specific subdirectory.
- Throws:
IOException- If creating the directory fails.
-
createNewAgiConfig
Creates a new agi session blueprint. Overridden by concrete containers to provide product-specific configurations (e.g., NetBeansAgiConfig).- Returns:
- The new agi configuration.
-
getEffectivelyEnabledProviders
Gets an unmodifiable list of all registered AI providers that are effectively enabled (the provider is enabled and either does not require an API key or has valid keys configured).- Returns:
- A list of effectively enabled providers.
-
hasAnyProviderConfigured
public boolean hasAnyProviderConfigured()Checks if any of the AI providers configured in the global template have at least one valid API key.- Returns:
- true if keys are configured, false otherwise.
-
createNewAgi
Authoritatively creates, configures, registers, and opens a brand-new Agi session using the user's preferred template.- Returns:
- The newly created and opened Agi session.
-
createNewBlankAgi
Authoritatively creates, configures, registers, and opens a brand-new Agi session using the clean framework config, bypassing any default template.- Returns:
- The newly created and opened Agi session.
-
createNewAgi
Authoritatively creates, configures, registers, and opens a brand-new Agi session with the provided configuration.Implementation details: This method orchestrates the creation, initial setup, pooling, and initial opening in one atomic weld. It is the primary entry point for spawning new intelligence instances.
- Parameters:
config- The session configuration.- Returns:
- The newly created and opened Agi session.
-
open
authoritatively requests that the specified agi session be opened and brought to the front in the host UI.- Parameters:
agi- The agi session to open.
-
close
Authoritatively requests that the specified agi session's UI tab or window be closed.- Parameters:
agi- The agi session to close.
-
getUI
-
registerActiveAgi
Internal logic for session pooling and common hook invocation.- Parameters:
agi- The session to register.
-
cloneAgi
Authoritatively clones an existing Agi session or template.Implementation details: Performs a deep clone using Kryo, assigns the new session ID, and updates the nickname. By placing this logic in the core container, we ensure architectural purity across different UI frameworks.
- Parameters:
agi- The source Agi session to clone.newSessionId- Optional custom ID for the cloned session or template. If null or blank, a random UUID is generated.- Returns:
- The newly cloned and registered Agi session.
-
cloneAgi
-
unregisterAgi
Unregisters a agi session from this configuration and triggers host-aware cleanup hooks.- Parameters:
agi- The agi session to unregister.
-
getActiveAgis
-
getAgi
-
getChildrenAgis
-
getOpenAgis
-
getSessionResourcesUnderPath
Resolves in-context resources under a given filesystem path across all open AGI sessions.- Parameters:
path- The filesystem path to check.- Returns:
- A map of open AGI sessions to their matching resources (only sessions with matching items).
-
onAgiRegistered
Hook invoked whenever a session enters the active pool.Implementation details: Attaches a reactive bridge listener to the session and its
ResourceManager. Whenever resources are registered or unregistered (via drag-and-drop, context menu, or AI tool calls), or when the session nickname or visibility changes,onSessionContextChanged(Agi, String)is invoked.- Parameters:
agi- The registered session.
-
onAgiUnregistered
Hook invoked whenever a session is removed from the active pool.Implementation details: Detaches the reactive bridge listener from the session and its resource manager, then notifies
onSessionContextChanged(Agi, String)to allow host IDEs to clear stale badges.- Parameters:
agi- The unregistered session.
-
onSessionContextChanged
Hook invoked whenever an AGI session's context, resources, nickname, or visibility state changes, or when a session is unregistered.Subclasses (such as NetBeans and IntelliJ containers) override this method to trigger host IDE project view tree repaints.
- Parameters:
agi- The session whose state changed.propertyName- The property that changed ("resources", "nickname", "open", or null on unregistration).
-
configureNewAgi
Hook invoked to perform initial post-birth configuration of a new Agi.Implementation details: Applies the global default provider and model from preferences if they are configured.
- Parameters:
agi- The new session.
-
onAgiOpened
Hook invoked when a session has been logically opened.- Parameters:
agi- The opened session.
-
onAgiClosed
Hook invoked when a session has been logically closed.- Parameters:
agi- The closed session.
-
getSessionsDir
Gets the directory where active agi sessions are stored.- Returns:
- The sessions directory path.
-
getSavedSessionsDir
Gets the directory where manually saved agi sessions are stored.- Returns:
- The saved sessions directory path.
-
getDisposedSessionsDir
Gets the directory where disposed agi sessions are moved.- Returns:
- The disposed sessions directory path.
-
getUnloadableSessionsDir
Gets the directory where agi sessions that failed to load are moved.- Returns:
- The unloadable sessions directory path.
-
ensureDir
Ensures that a given directory exists on disk, creating it if missing.- Parameters:
dir- The directory path to verify and create.- Returns:
- The verified directory path.
- Throws:
IOException- If creating the directory fails.
-
getSubdirectory
Resolves a named subdirectory against a parent path, ensuring it exists on disk.- Parameters:
parent- The parent directory path.subdirName- The name of the child directory.- Returns:
- The verified subdirectory path.
- Throws:
IOException- If directory creation fails.
-
autoSaveSession
Performs an automatic backup of the session using Kryo serialization.Implementation details: Only proceeds if the agi is in a stable state (IDLE, TOOL_PROMPT, etc.) to prevent serialization during volatile operations like streaming.
- Parameters:
agi- The agi session to save.reason- A description of why the save was triggered.- Throws:
IOException
-
getPersistenceDir
Gets the primary persistence directory for the given AGI session or template.- Parameters:
agi- The AGI instance.- Returns:
- The templates directory if template, or sessions directory if active session.
- Throws:
IOException- If creating the directory fails.
-
saveAgi
Saves the AGI instance to its designated persistence directory.- Parameters:
agi- The AGI instance to save.- Throws:
IOException- If saving fails.
-
manualSaveSession
Manually saves the session to the 'saved' directory, or to templates if template.- Parameters:
agi- The agi session to save.- Throws:
IOException
-
saveAgiTo
Serializes and saves an Agi session to a specific directory using Kryo. This method is synchronized on the Agi instance to prevent concurrent write issues.- Parameters:
agi- The Agi session to save.dir- The destination directory.- Throws:
IOException- If saving fails.
-
dispose
Permanently disposes of a agi session or template, shutting it down and moving its serialized file to the 'disposed' directory.- Parameters:
agi- The agi session to dispose.
-
importSession
Imports an Agi session from an external file. The session is assigned a new ID to avoid collisions and registered as a new active agi.- Parameters:
path- The path to the serialized session file.- Returns:
- The imported Agi session.
- Throws:
IOException- If reading the session file fails.
-
loadAgi
-
loadAgis
Scans a directory for .kryo files in parallel, deserializes each vialoadAgi(Path), and invokes the registration callback as each finishes loading.- Parameters:
dir- The directory to load from.registrationCallback- The callback to invoke for each successfully loaded AGI.- Returns:
- The count of successfully loaded AGIs.
-
loadSessions
public int loadSessions()Scans the sessions directory and loads all serialized active Agi sessions.- Returns:
- The number of sessions loaded.
-
isTemplate
Checks if the given session is an AGI template managed by this container.- Parameters:
agi- The AGI session to check.- Returns:
- true if the session is registered in the templates list.
-
loadTemplatesFromDisk
public int loadTemplatesFromDisk()Scans the templates directory and loads all serialized AGI templates into memory.- Returns:
- The number of templates loaded from disk.
-
getTemplates
-
getDefaultTemplate
Finds the default template whose session ID is "default" (case-insensitive).- Returns:
- The default template, or null if none is configured.
-
registerTemplate
Registers a template instance into the container's template registry and fires a property change event. If a template with the same session ID already exists, it is replaced.- Parameters:
templateAgi- The template to register.
-
unregisterTemplate
Unregisters a template from the container's template registry and fires a property change event.- Parameters:
templateAgi- The template to unregister.
-
createNewAgiFromTemplate
-
createNewAgiFromTemplate
-
createTemplateFromSession
public Agi createTemplateFromSession(@NonNull @NonNull Agi sessionAgi, @NonNull @NonNull String templateId) throws IOException Creates and saves a new template cloned from an active AGI session, preserving its nickname.- Parameters:
sessionAgi- The source session to base the template on.templateId- The unique template ID (used as sessionId and filename).- Returns:
- The created template Agi.
- Throws:
IOException- If saving fails.
-
createTemplate
Creates, configures, and saves a fresh new template.- Parameters:
templateId- The unique template ID.- Returns:
- The created template Agi.
- Throws:
IOException- If saving fails.
-
startKeyFileWatcherThread
private void startKeyFileWatcherThread()Starts a dedicated low-priority daemon thread that polls API key files once per second.This ensures that external edits to key files on disk are detected within 1 second without placing any synchronous disk I/O onto the Swing Event Dispatch Thread (EDT).
-
shutdown
public void shutdown()Shuts down the container, interrupts the key watcher thread, and terminates the shared executor. -
getWorkDir
Gets the root Anahata AI working directory (e.g., ~/.anahata/asi or $SNAP_USER_DATA/.anahata/asi).- Returns:
- The root working directory path.
-
getWorkDirSubDir
Gets a named subdirectory within the global root working directory, creating it if it doesn't exist. This is used for shared resources like provider configurations. e.g., ~/.anahata/asi/gemini- Parameters:
name- The name of the subdirectory.- Returns:
- The Path object for the subdirectory.
-

