agent-swarm-kit
Version:
A TypeScript library for building orchestrated framework-agnostic multi-agent AI systems
977 lines (966 loc) • 882 kB
TypeScript
import * as functools_kit from 'functools-kit';
import { SortedArray, TSubject, Subject, ToolRegistry, LimitedSet } from 'functools-kit';
import * as di_scoped from 'di-scoped';
/**
* Interface representing an incoming message received by the swarm system.
* Encapsulates a message entering the system, typically from a client (e.g., user input), processed by agents (e.g., ClientAgent.execute) or sessions (e.g., ISession.connect).
* Used to convey data from an external source to an agent, potentially triggering actions like history updates (e.g., IHistory.push) or event emissions (e.g., IBus.emit "commit-user-message").
*/
interface IIncomingMessage {
/**
* The unique identifier of the client sending the message.
* Identifies the originating client session, matching clientId in runtime params (e.g., this.params.clientId in ClientAgent), ensuring the message is tied to a specific sender.
* Example: "client-123" for a user session submitting a command.
* @type {string}
*/
clientId: string;
/**
* The content or payload of the incoming message.
* Contains the raw data sent by the client, typically a string (e.g., user command, query), processed as input by agents (e.g., incoming in ClientAgent.execute).
* Example: "What is the weather?" for a user query received by an agent.
* @type {string}
*/
data: string;
/**
* The name of the agent designated to receive or process the message.
* Links the message to a specific agent instance (e.g., this.params.agentName in ClientAgent), aligning with AgentName from IAgentParams for routing or context.
* Example: "WeatherAgent" for an agent handling weather-related queries.
* @type {AgentName}
*/
agentName: AgentName;
}
/**
* Interface representing an outgoing message sent from the swarm system.
* Encapsulates a message dispatched to a client, typically an agent’s response or output (e.g., ClientAgent._emitOutput), delivered via sessions (e.g., ISession.emit) or events (e.g., IBus.emit "emit-output").
* Used to communicate results or notifications back to the client, reflecting the system’s response to incoming messages or internal actions.
*/
interface IOutgoingMessage {
/**
* The unique identifier of the client receiving the message.
* Specifies the target client session, matching clientId in runtime params (e.g., this.params.clientId in ClientAgent), ensuring delivery to the intended recipient.
* Example: "client-123" for a user session receiving a response.
* @type {string}
*/
clientId: string;
/**
* The content or payload of the outgoing message.
* Contains the data sent to the client, typically a string (e.g., processed result, assistant response), generated by agents (e.g., result in ClientAgent._emitOutput).
* Example: "The weather is sunny." for an agent’s response to a query.
* @type {string}
*/
data: string;
/**
* The name of the agent sending the message.
* Identifies the originating agent instance (e.g., this.params.agentName in ClientAgent), aligning with AgentName from IAgentParams to indicate the source of the response.
* Example: "WeatherAgent" for an agent replying to a client query.
* @type {AgentName}
*/
agentName: AgentName;
}
/**
* Interface representing a logging mechanism for the swarm system.
* Provides methods to record messages at different severity levels, used across components like agents, sessions, states, storage, swarms, history, embeddings, completions, and policies.
* Logs are utilized to track lifecycle events (e.g., initialization, disposal), operational details (e.g., tool calls, message emissions), validation outcomes (e.g., policy checks), and errors (e.g., persistence failures), aiding in debugging, monitoring, and auditing.
*/
interface ILogger {
/**
* Logs a general-purpose message.
* Used throughout the swarm system to record significant events or state changes, such as agent execution, session connections, or storage updates.
* @param {string} topic - The category or context of the log message (e.g., "AgentExecution", "StorageUpsert").
* @param {...any[]} args - Variable arguments representing the message content, which can include strings, objects, or other data types for flexible logging.
*/
log(topic: string, ...args: any[]): void;
/**
* Logs a debug-level message.
* Employed for detailed diagnostic information, such as intermediate states during agent tool calls, swarm navigation changes, or embedding creation processes, typically enabled in development or troubleshooting scenarios.
* @param {string} topic - The category or context of the debug message (e.g., "ToolValidation", "EmbeddingSimilarity").
* @param {...any[]} args - Variable arguments representing the debug content, often detailed data like parameters, stack traces, or internal states.
*/
debug(topic: string, ...args: any[]): void;
/**
* Logs an info-level message.
* Used to record informational updates, such as successful completions, policy validations, or history commits, providing a high-level overview of system activity without excessive detail.
* @param {string} topic - The category or context of the info message (e.g., "SessionInit", "PolicyBan").
* @param {...any[]} args - Variable arguments representing the informational content, typically concise summaries or status updates.
*/
info(topic: string, ...args: any[]): void;
}
/**
* Type representing an array of numbers as embeddings.
* Used to encode text or data for similarity comparisons in storage or search operations.
* @typedef {number[]} Embeddings
*/
type Embeddings = number[];
/**
* Interface representing callbacks for embedding lifecycle events.
* Provides hooks for creation and comparison of embeddings.
*/
interface IEmbeddingCallbacks {
/**
* Callback triggered when an embedding is created.
* Useful for logging or post-processing the generated embeddings.
* @param {string} text - The input text used to generate the embedding.
* @param {Embeddings} embeddings - The resulting embedding as an array of numbers.
* @param {string} clientId - The unique ID of the client associated with the embedding.
* @param {EmbeddingName} embeddingName - The unique name of the embedding mechanism.
*/
onCreate(text: string, embeddings: Embeddings, clientId: string, embeddingName: EmbeddingName): void;
/**
* Callback triggered when two embeddings are compared for similarity.
* Useful for logging or analyzing similarity results.
* @param {string} text1 - The first text whose embedding was used in the comparison.
* @param {string} text2 - The second text whose embedding was used in the comparison.
* @param {number} similarity - The similarity score between the two embeddings (e.g., cosine similarity).
* @param {string} clientId - The unique ID of the client associated with the comparison.
* @param {EmbeddingName} embeddingName - The unique name of the embedding mechanism.
*/
onCompare(text1: string, text2: string, similarity: number, clientId: string, embeddingName: EmbeddingName): void;
}
/**
* Interface representing the schema for configuring an embedding mechanism.
* Defines how embeddings are created and compared within the swarm.
*/
interface IEmbeddingSchema {
/** Optional flag to enable serialization of navigation stack and active agent state to persistent storage (e.g., hard drive). */
persist?: boolean;
/** The unique name of the embedding mechanism within the swarm. */
embeddingName: EmbeddingName;
/**
* Creates an embedding from the provided text.
* Typically used for indexing or search operations in storage.
* @param {string} text - The text to encode into an embedding.
* @returns {Promise<Embeddings>} A promise resolving to the generated embedding as an array of numbers.
* @throws {Error} If embedding creation fails (e.g., due to invalid text or model errors).
*/
createEmbedding(text: string, embeddingName: EmbeddingName): Promise<Embeddings>;
/**
* Calculates the similarity between two embeddings.
* Commonly used for search or ranking operations (e.g., cosine similarity).
* @param {Embeddings} a - The first embedding to compare.
* @param {Embeddings} b - The second embedding to compare.
* @returns {Promise<number>} A promise resolving to the similarity score (typically between -1 and 1).
* @throws {Error} If similarity calculation fails (e.g., due to invalid embeddings or computation errors).
*/
calculateSimilarity(a: Embeddings, b: Embeddings): Promise<number>;
/**
* Stores an embedding vector for a specific string hash, persisting it for future retrieval.
* Used to cache computed embeddings to avoid redundant processing.
* @param embeddings - Array of numerical values representing the embedding vector.
* @param embeddingName - The identifier of the embedding type.
* @param stringHash - The hash of the string for which the embedding was generated.
* @returns A promise that resolves when the embedding vector is persisted.
* @throws {Error} If writing to storage fails (e.g., permissions or disk space).
*/
writeEmbeddingCache?: (embeddings: number[], embeddingName: EmbeddingName, stringHash: string) => Promise<void> | void;
/**
* Retrieves the embedding vector for a specific string hash, returning null if not found.
* Used to check if a precomputed embedding exists in the cache.
* @param embeddingName - The identifier of the embedding type.
* @param stringHash - The hash of the string for which the embedding was generated.
* @returns A promise resolving to the embedding vector or null if not cached.
* @throws {Error} If reading from storage fails (e.g., file corruption).
*/
readEmbeddingCache?: (embeddingName: EmbeddingName, stringHash: string) => Promise<number[] | null> | number[] | null;
/** Optional partial set of callbacks for embedding events, allowing customization of creation and comparison. */
callbacks?: Partial<IEmbeddingCallbacks>;
}
/**
* Type representing the unique name of an embedding mechanism within the swarm.
* @typedef {string} EmbeddingName
*/
type EmbeddingName = string;
/**
* Type representing the unique identifier for storage items.
* @typedef {string | number} StorageId
*/
type StorageId = string | number;
/**
* Interface representing the data structure stored in the storage.
* Defines the minimum required properties for storage items.
*/
interface IStorageData {
/** The unique identifier for the storage item, used for retrieval and removal. */
id: StorageId;
}
/**
* Interface representing the schema for storage configuration.
* Defines how storage behaves, including persistence, indexing, and data access.
* @template T - The type of the storage data, defaults to IStorageData.
*/
interface IStorageSchema<T extends IStorageData = IStorageData> {
/** Optional flag to enable serialization of storage data to persistent storage (e.g., hard drive). */
persist?: boolean;
/** Optional description for documentation purposes, aiding in storage usage understanding. */
docDescription?: string;
/** Optional flag indicating whether the storage instance is shared across all agents for a client. */
shared?: boolean;
/**
* Optional function to retrieve data from the storage, overriding default behavior.
* @param {string} clientId - The unique ID of the client requesting the data.
* @param {StorageName} storageName - The unique name of the storage.
* @param {T[]} defaultValue - The default data to return if no data is found.
* @returns {Promise<T[]> | T[]} The stored data, synchronously or asynchronously.
*/
getData?: (clientId: string, storageName: StorageName, defaultValue: T[]) => Promise<T[]> | T[];
/**
* Optional function to persist storage data to the hard drive, overriding default behavior.
* @param {T[]} data - The data to persist.
* @param {string} clientId - The unique ID of the client updating the storage.
* @param {StorageName} storageName - The unique name of the storage.
* @returns {Promise<void> | void} A promise that resolves when data is persisted, or void if synchronous.
* @throws {Error} If persistence fails (e.g., due to disk errors).
*/
setData?: (data: T[], clientId: string, storageName: StorageName) => Promise<void> | void;
/**
* Function to generate an index for a storage item, used for search and retrieval.
* @param {T} item - The storage item to index.
* @returns {Promise<string> | string} The index string for the item, synchronously or asynchronously.
*/
createIndex(item: T): Promise<string> | string | Record<string, string> | Promise<Record<string, string>>;
/** The name of the embedding mechanism used for indexing and searching storage data. */
embedding: EmbeddingName;
/** The unique name of the storage within the swarm. */
storageName: StorageName;
/** Optional partial set of lifecycle callbacks for storage events, allowing customization. */
callbacks?: Partial<IStorageCallbacks<T>>;
/**
* Optional function to provide the default data for the storage, resolved in persistence logic.
* @param {string} clientId - The unique ID of the client requesting the default data.
* @param {StorageName} storageName - The unique name of the storage.
* @returns {Promise<T[]> | T[]} The default data array, synchronously or asynchronously.
*/
getDefaultData?: (clientId: string, storageName: StorageName) => Promise<T[]> | T[];
}
/**
* Interface representing callbacks for storage lifecycle and operational events.
* Provides hooks for updates, searches, initialization, and disposal.
* @template T - The type of the storage data, defaults to IStorageData.
*/
interface IStorageCallbacks<T extends IStorageData = IStorageData> {
/**
* Callback triggered when storage data is updated (e.g., via upsert or remove).
* Useful for logging or synchronizing state.
* @param {T[]} items - The updated array of storage items.
* @param {string} clientId - The unique ID of the client associated with the storage.
* @param {StorageName} storageName - The unique name of the storage.
*/
onUpdate: (items: T[], clientId: string, storageName: StorageName) => void;
/**
* Callback triggered during a search operation on the storage.
* @param {string} search - The search query used to filter items.
* @param {SortedArray<T>} index - The sorted array of storage items based on the search.
* @param {string} clientId - The unique ID of the client performing the search.
* @param {StorageName} storageName - The unique name of the storage.
*/
onSearch: (search: string, index: SortedArray<T>, clientId: string, storageName: StorageName) => void;
/**
* Callback triggered when the storage is initialized.
* Useful for setup or logging.
* @param {string} clientId - The unique ID of the client associated with the storage.
* @param {StorageName} storageName - The unique name of the storage.
*/
onInit: (clientId: string, storageName: StorageName) => void;
/**
* Callback triggered when the storage is disposed of.
* Useful for cleanup or logging.
* @param {string} clientId - The unique ID of the client associated with the storage.
* @param {StorageName} storageName - The unique name of the storage.
*/
onDispose: (clientId: string, storageName: StorageName) => void;
}
/**
* Interface representing the runtime parameters for storage management.
* Extends the storage schema with client-specific and embedding-related dependencies.
* @template T - The type of the storage data, defaults to IStorageData.
* @extends {IStorageSchema<T>}
* @extends {Partial<IEmbeddingCallbacks>}
*/
interface IStorageParams<T extends IStorageData = IStorageData> extends IStorageSchema<T>, Partial<IEmbeddingCallbacks> {
/** The unique ID of the client associated with the storage instance. */
clientId: string;
/**
* Function to calculate similarity between embeddings, inherited from the embedding schema.
* Used for search operations.
*/
calculateSimilarity: IEmbeddingSchema["calculateSimilarity"];
/**
* Stores an embedding vector for a specific string hash, persisting it for future retrieval.
* Used to cache computed embeddings to avoid redundant processing.
* @param embeddings - Array of numerical values representing the embedding vector.
* @param embeddingName - The identifier of the embedding type.
* @param stringHash - The hash of the string for which the embedding was generated.
* @returns A promise that resolves when the embedding vector is persisted.
* @throws {Error} If writing to storage fails (e.g., permissions or disk space).
*/
writeEmbeddingCache: IEmbeddingSchema["writeEmbeddingCache"];
/**
* Retrieves the embedding vector for a specific string hash, returning null if not found.
* Used to check if a precomputed embedding exists in the cache.
* @param embeddingName - The identifier of the embedding type.
* @param stringHash - The hash of the string for which the embedding was generated.
* @returns A promise resolving to the embedding vector or null if not cached.
* @throws {Error} If reading from storage fails (e.g., file corruption).
*/
readEmbeddingCache: IEmbeddingSchema["readEmbeddingCache"];
/**
* Function to create an embedding for storage items, inherited from the embedding schema.
* Used for indexing.
*/
createEmbedding: IEmbeddingSchema["createEmbedding"];
/** The unique name of the storage within the swarm (redundant with schema but included for clarity). */
storageName: StorageName;
/** The logger instance for recording storage-related activity and errors. */
logger: ILogger;
/** The bus instance for event communication within the swarm. */
bus: IBus;
}
/**
* Interface representing the runtime storage management API.
* Provides methods to manipulate and query storage data.
* @template T - The type of the storage data, defaults to IStorageData.
*/
interface IStorage<T extends IStorageData = IStorageData> {
/**
* Retrieves a specified number of items from the storage based on a search query.
* Uses embeddings for similarity-based retrieval.
* @param {string} search - The search query to filter items.
* @param {number} total - The maximum number of items to retrieve.
* @param {number} [score] - Optional similarity score threshold for filtering items.
* @returns {Promise<T[]>} A promise resolving to an array of matching storage items.
* @throws {Error} If retrieval fails (e.g., due to embedding issues or invalid query).
*/
take(search: string, total: number, score?: number): Promise<T[]>;
/**
* Inserts or updates an item in the storage.
* Updates the index and persists data if configured.
* @param {T} item - The item to upsert into the storage.
* @returns {Promise<void>} A promise that resolves when the upsert operation is complete.
* @throws {Error} If upsert fails (e.g., due to persistence issues or invalid item).
*/
upsert(item: T): Promise<void>;
/**
* Removes an item from the storage by its ID.
* Updates the index and persists changes if configured.
* @param {IStorageData["id"]} itemId - The ID of the item to remove.
* @returns {Promise<void>} A promise that resolves when the removal operation is complete.
* @throws {Error} If removal fails (e.g., due to persistence issues or invalid ID).
*/
remove(itemId: IStorageData["id"]): Promise<void>;
/**
* Retrieves an item from the storage by its ID.
* @param {IStorageData["id"]} itemId - The ID of the item to retrieve.
* @returns {Promise<T | null>} A promise resolving to the item if found, or null if not found.
* @throws {Error} If retrieval fails (e.g., due to internal errors).
*/
get(itemId: IStorageData["id"]): Promise<T | null>;
/**
* Lists all items in the storage, optionally filtered by a predicate.
* @param {(item: T) => boolean} [filter] - Optional function to filter items; only items returning true are included.
* @returns {Promise<T[]>} A promise resolving to an array of storage items.
* @throws {Error} If listing fails (e.g., due to persistence issues).
*/
list(filter?: (item: T) => boolean): Promise<T[]>;
/**
* Clears all items from the storage, resetting it to an empty state.
* Persists changes if configured.
* @returns {Promise<void>} A promise that resolves when the clear operation is complete.
* @throws {Error} If clearing fails (e.g., due to persistence issues).
*/
clear(): Promise<void>;
}
/**
* Type representing the unique name of a storage within the swarm.
* @typedef {string} StorageName
*/
type StorageName = string;
/**
* Type representing the data structure of a state.
* Can be any type, serving as a generic placeholder for state values.
* @typedef {any} IStateData
*/
type IStateData = any;
/**
* Interface representing a middleware function for state management.
* Allows modification or validation of state during lifecycle operations.
* @template T - The type of the state data, defaults to IStateData.
*/
interface IStateMiddleware<T extends IStateData = IStateData> {
/**
* Processes the state, potentially modifying it before it’s finalized.
* @param {T} state - The current state data to process.
* @param {string} clientId - The unique ID of the client associated with the state.
* @param {StateName} stateName - The unique name of the state.
* @returns {Promise<T>} A promise resolving to the updated state after middleware processing.
* @throws {Error} If middleware processing fails or validation conditions are not met.
*/
(state: T, clientId: string, stateName: StateName): Promise<T>;
}
/**
* Interface representing callbacks for state lifecycle events.
* Provides hooks for initialization, disposal, and state transitions.
* @template T - The type of the state data, defaults to IStateData.
*/
interface IStateCallbacks<T extends IStateData = IStateData> {
/**
* Callback triggered when the state is initialized.
* Useful for setup or logging.
* @param {string} clientId - The unique ID of the client associated with the state.
* @param {StateName} stateName - The unique name of the state.
*/
onInit: (clientId: string, stateName: StateName) => void;
/**
* Callback triggered when the state is disposed of.
* Useful for cleanup or logging.
* @param {string} clientId - The unique ID of the client associated with the state.
* @param {StateName} stateName - The unique name of the state.
*/
onDispose: (clientId: string, stateName: StateName) => void;
/**
* Callback triggered when the state is loaded from storage or initialized.
* @param {T} state - The loaded state data.
* @param {string} clientId - The unique ID of the client associated with the state.
* @param {StateName} stateName - The unique name of the state.
*/
onLoad: (state: T, clientId: string, stateName: StateName) => void;
/**
* Callback triggered when the state is read.
* Useful for monitoring or logging read operations.
* @param {T} state - The current state data being read.
* @param {string} clientId - The unique ID of the client associated with the state.
* @param {StateName} stateName - The unique name of the state.
*/
onRead: (state: T, clientId: string, stateName: StateName) => void;
/**
* Callback triggered when the state is written or updated.
* Useful for tracking changes or triggering side effects.
* @param {T} state - The updated state data being written.
* @param {string} clientId - The unique ID of the client associated with the state.
* @param {StateName} stateName - The unique name of the state.
*/
onWrite: (state: T, clientId: string, stateName: StateName) => void;
}
/**
* Interface representing the schema for state management.
* Defines the configuration and behavior of a state within the swarm.
* @template T - The type of the state data, defaults to IStateData.
*/
interface IStateSchema<T extends IStateData = IStateData> {
/** Optional flag to enable serialization of state values to persistent storage (e.g., hard drive). */
persist?: boolean;
/** Optional description for documentation purposes, aiding in state usage understanding. */
docDescription?: string;
/** Optional flag indicating whether the state can be shared across multiple agents. */
shared?: boolean;
/** The unique name of the state within the swarm. */
stateName: StateName;
/**
* Function to retrieve or compute the default state value.
* @param {string} clientId - The unique ID of the client requesting the state.
* @param {StateName} stateName - The unique name of the state.
* @returns {T | Promise<T>} The default state value, synchronously or asynchronously.
*/
getDefaultState: (clientId: string, stateName: StateName) => T | Promise<T>;
/**
* Optional function to retrieve the current state, with a fallback to the default state.
* Overrides default state retrieval behavior if provided.
* @param {string} clientId - The unique ID of the client requesting the state.
* @param {StateName} stateName - The unique name of the state.
* @param {T} defaultState - The default state value to use if no state is found.
* @returns {T | Promise<T>} The current state value, synchronously or asynchronously.
*/
getState?: (clientId: string, stateName: StateName, defaultState: T) => T | Promise<T>;
/**
* Optional function to set or update the state.
* Overrides default state setting behavior if provided.
* @param {T} state - The new state value to set.
* @param {string} clientId - The unique ID of the client updating the state.
* @param {StateName} stateName - The unique name of the state.
* @returns {Promise<void> | void} A promise that resolves when the state is set, or void if synchronous.
* @throws {Error} If the state update fails (e.g., due to persistence issues).
*/
setState?: (state: T, clientId: string, stateName: StateName) => Promise<void> | void;
/** Optional array of middleware functions to process the state during lifecycle operations. */
middlewares?: IStateMiddleware<T>[];
/** Optional partial set of lifecycle callbacks for the state, allowing customization of state events. */
callbacks?: Partial<IStateCallbacks<T>>;
}
/**
* Interface representing the runtime parameters for state management.
* Extends the state schema with client-specific runtime dependencies.
* @template T - The type of the state data, defaults to IStateData.
* @extends {IStateSchema<T>}
*/
interface IStateParams<T extends IStateData = IStateData> extends IStateSchema<T> {
/** The unique ID of the client associated with the state instance. */
clientId: string;
/** The logger instance for recording state-related activity and errors. */
logger: ILogger;
/** The bus instance for event communication within the swarm. */
bus: IBus;
}
/**
* Interface representing the runtime state management API.
* Provides methods to get, set, and clear the state.
* @template T - The type of the state data, defaults to IStateData.
*/
interface IState<T extends IStateData = IStateData> {
/**
* Retrieves the current state value.
* Applies any configured middleware or custom `getState` logic from the schema.
* @returns {Promise<T>} A promise resolving to the current state value.
* @throws {Error} If state retrieval fails (e.g., due to persistence issues or invalid configuration).
*/
getState: () => Promise<T>;
/**
* Updates the state using a dispatch function that computes the new state from the previous state.
* Applies any configured middleware or custom `setState` logic from the schema.
* @param {(prevState: T) => Promise<T>} dispatchFn - An async function that takes the previous state and returns the new state.
* @returns {Promise<T>} A promise resolving to the updated state value.
* @throws {Error} If state update fails (e.g., due to middleware errors or persistence issues).
*/
setState: (dispatchFn: (prevState: T) => Promise<T>) => Promise<T>;
/**
* Resets the state to its initial default value.
* Reverts to the value provided by `getDefaultState` in the schema.
* @returns {Promise<T>} A promise resolving to the initial state value.
* @throws {Error} If state clearing fails (e.g., due to persistence issues or invalid default state).
*/
clearState: () => Promise<T>;
}
/**
* Type representing the unique name of a state within the swarm.
* @typedef {string} StateName
*/
type StateName = string;
/**
* Interface representing callbacks for policy lifecycle and validation events.
* Provides hooks for initialization, validation, and ban actions.
*/
interface IPolicyCallbacks {
/**
* Optional callback triggered when the policy is initialized.
* Useful for setup or logging.
* @param {PolicyName} policyName - The unique name of the policy.
*/
onInit?: (policyName: PolicyName) => void;
/**
* Optional callback triggered to validate incoming messages.
* Useful for logging or monitoring input validation.
* @param {string} incoming - The incoming message to validate.
* @param {SessionId} clientId - The unique session ID of the client sending the message.
* @param {SwarmName} swarmName - The unique name of the swarm.
* @param {PolicyName} policyName - The unique name of the policy.
*/
onValidateInput?: (incoming: string, clientId: SessionId, swarmName: SwarmName, policyName: PolicyName) => void;
/**
* Optional callback triggered to validate outgoing messages.
* Useful for logging or monitoring output validation.
* @param {string} outgoing - The outgoing message to validate.
* @param {SessionId} clientId - The unique session ID of the client receiving the message.
* @param {SwarmName} swarmName - The unique name of the swarm.
* @param {PolicyName} policyName - The unique name of the policy.
*/
onValidateOutput?: (outgoing: string, clientId: SessionId, swarmName: SwarmName, policyName: PolicyName) => void;
/**
* Optional callback triggered when a client is banned.
* Useful for logging or triggering ban-related actions.
* @param {SessionId} clientId - The unique session ID of the banned client.
* @param {SwarmName} swarmName - The unique name of the swarm.
* @param {PolicyName} policyName - The unique name of the policy.
*/
onBanClient?: (clientId: SessionId, swarmName: SwarmName, policyName: PolicyName) => void;
/**
* Optional callback triggered when a client is unbanned.
* Useful for logging or triggering unban-related actions.
* @param {SessionId} clientId - The unique session ID of the unbanned client.
* @param {SwarmName} swarmName - The unique name of the swarm.
* @param {PolicyName} policyName - The unique name of the policy.
*/
onUnbanClient?: (clientId: SessionId, swarmName: SwarmName, policyName: PolicyName) => void;
}
/**
* Interface representing a policy enforcement mechanism.
* Manages client bans and validates input/output messages within the swarm.
*/
interface IPolicy {
/**
* Checks if a client is currently banned under this policy.
* @param {SessionId} clientId - The unique session ID of the client to check.
* @param {SwarmName} swarmName - The unique name of the swarm.
* @returns {Promise<boolean>} A promise resolving to true if the client is banned, false otherwise.
* @throws {Error} If the ban status check fails (e.g., due to storage issues).
*/
hasBan(clientId: SessionId, swarmName: SwarmName): Promise<boolean>;
/**
* Retrieves the ban message for a banned client.
* @param {SessionId} clientId - The unique session ID of the banned client.
* @param {SwarmName} swarmName - The unique name of the swarm.
* @returns {Promise<string>} A promise resolving to the ban message for the client.
* @throws {Error} If retrieving the ban message fails (e.g., due to missing configuration).
*/
getBanMessage(clientId: SessionId, swarmName: SwarmName): Promise<string>;
/**
* Validates an incoming message against the policy rules.
* @param {string} incoming - The incoming message to validate.
* @param {SessionId} clientId - The unique session ID of the client sending the message.
* @param {SwarmName} swarmName - The unique name of the swarm.
* @returns {Promise<boolean>} A promise resolving to true if the input is valid, false otherwise.
* @throws {Error} If validation fails unexpectedly (e.g., due to internal errors).
*/
validateInput(incoming: string, clientId: SessionId, swarmName: SwarmName): Promise<boolean>;
/**
* Validates an outgoing message against the policy rules.
* @param {string} outgoing - The outgoing message to validate.
* @param {SessionId} clientId - The unique session ID of the client receiving the message.
* @param {SwarmName} swarmName - The unique name of the swarm.
* @returns {Promise<boolean>} A promise resolving to true if the output is valid, false otherwise.
* @throws {Error} If validation fails unexpectedly (e.g., due to internal errors).
*/
validateOutput(outgoing: string, clientId: SessionId, swarmName: SwarmName): Promise<boolean>;
/**
* Bans a client under this policy, adding them to the banned list.
* @param {SessionId} clientId - The unique session ID of the client to ban.
* @param {SwarmName} swarmName - The unique name of the swarm.
* @returns {Promise<void>} A promise that resolves when the client is banned.
* @throws {Error} If banning the client fails (e.g., due to persistence issues).
*/
banClient(clientId: SessionId, swarmName: SwarmName): Promise<void>;
/**
* Unbans a client under this policy, removing them from the banned list.
* @param {SessionId} clientId - The unique session ID of the client to unban.
* @param {SwarmName} swarmName - The unique name of the swarm.
* @returns {Promise<void>} A promise that resolves when the client is unbanned.
* @throws {Error} If unbanning the client fails (e.g., due to persistence issues).
*/
unbanClient(clientId: SessionId, swarmName: SwarmName): Promise<void>;
}
/**
* Interface representing the schema for configuring a policy.
* Defines how policies enforce rules and manage bans within the swarm.
*/
interface IPolicySchema {
/** Optional flag to enable serialization of banned clients to persistent storage (e.g., hard drive). */
persist?: boolean;
/** Optional description for documentation purposes, aiding in policy usage understanding. */
docDescription?: string;
/** The unique name of the policy within the swarm. */
policyName: PolicyName;
/** Optional default message to display when a client is banned, overridden by getBanMessage if provided. */
banMessage?: string;
/** Optional flag to automatically ban a client immediately after failed validation. */
autoBan?: boolean;
/**
* Optional function to retrieve a custom ban message for a client.
* Overrides the default banMessage if provided.
* @param {SessionId} clientId - The unique session ID of the banned client.
* @param {PolicyName} policyName - The unique name of the policy.
* @param {SwarmName} swarmName - The unique name of the swarm.
* @returns {Promise<string | null> | string | null} The ban message or null, synchronously or asynchronously.
*/
getBanMessage?: (clientId: SessionId, policyName: PolicyName, swarmName: SwarmName) => Promise<string | null> | string | null;
/**
* Retrieves the list of currently banned clients under this policy.
* @param {PolicyName} policyName - The unique name of the policy.
* @param {SwarmName} swarmName - The unique name of the swarm.
* @returns {SessionId[] | Promise<SessionId[]>} An array of banned session IDs, synchronously or asynchronously.
*/
getBannedClients?: (policyName: PolicyName, swarmName: SwarmName) => SessionId[] | Promise<SessionId[]>;
/**
* Optional function to set the list of banned clients.
* Overrides default ban list management if provided.
* @param {SessionId[]} clientIds - An array of session IDs to ban.
* @param {PolicyName} policyName - The unique name of the policy.
* @param {SwarmName} swarmName - The unique name of the swarm.
* @returns {Promise<void> | void} A promise that resolves when the ban list is updated, or void if synchronous.
* @throws {Error} If updating the ban list fails (e.g., due to persistence issues).
*/
setBannedClients?: (clientIds: SessionId[], policyName: PolicyName, swarmName: SwarmName) => Promise<void> | void;
/**
* Optional function to validate incoming messages against custom policy rules.
* Overrides default validation if provided.
* @param {string} incoming - The incoming message to validate.
* @param {SessionId} clientId - The unique session ID of the client sending the message.
* @param {PolicyName} policyName - The unique name of the policy.
* @param {SwarmName} swarmName - The unique name of the swarm.
* @returns {Promise<boolean> | boolean} True if the input is valid, false otherwise, synchronously or asynchronously.
*/
validateInput?: (incoming: string, clientId: SessionId, policyName: PolicyName, swarmName: SwarmName) => Promise<boolean> | boolean;
/**
* Optional function to validate outgoing messages against custom policy rules.
* Overrides default validation if provided.
* @param {string} outgoing - The outgoing message to validate.
* @param {SessionId} clientId - The unique session ID of the client receiving the message.
* @param {PolicyName} policyName - The unique name of the policy.
* @param {SwarmName} swarmName - The unique name of the swarm.
* @returns {Promise<boolean> | boolean} True if the output is valid, false otherwise, synchronously or asynchronously.
*/
validateOutput?: (outgoing: string, clientId: SessionId, policyName: PolicyName, swarmName: SwarmName) => Promise<boolean> | boolean;
/** Optional set of callbacks for policy events, allowing customization of validation and ban actions. */
callbacks?: IPolicyCallbacks;
}
/**
* Interface representing the parameters required to initialize a policy.
* Extends the policy schema with runtime dependencies and full callback support.
* @extends {IPolicySchema}
* @extends {IPolicyCallbacks}
*/
interface IPolicyParams extends IPolicySchema, IPolicyCallbacks {
/** The logger instance for recording policy-related activity and errors. */
logger: ILogger;
/** The bus instance for event communication within the swarm. */
bus: IBus;
}
/**
* Type representing the unique name of a policy within the swarm.
* @typedef {string} PolicyName
*/
type PolicyName = string;
/**
* @module StateChangeContract
* @description Defines an interface for state change event handling using a subject pattern.
*/
/**
* @interface IStateChangeContract
* @description Contract for handling state change events, providing a subject to subscribe to state updates.
*/
interface IStateChangeContract {
/**
* @property {TSubject<StateName>} stateChanged
* @description A subject that emits state names when changes occur, allowing subscribers to react to state updates.
*/
stateChanged: TSubject<StateName>;
}
/**
* @module ComputeInterface
* @description Defines interfaces and types for compute-related operations, including schemas, middleware, callbacks, and contracts.
*/
/**
* @typedef {any} IComputeData
* @description Generic type for compute data, allowing flexibility in data structure.
*/
type IComputeData = any;
/**
* @interface IComputeMiddleware
* @template T - Type extending IComputeData.
* @description Defines a middleware function for processing compute data.
*/
interface IComputeMiddleware<T extends IComputeData = IComputeData> {
/**
* @param {T} state - The current compute data.
* @param {string} clientId - The client identifier.
* @param {ComputeName} computeName - The name of the compute.
* @returns {Promise<T>} The processed compute data.
*/
(state: T, clientId: string, computeName: ComputeName): Promise<T>;
}
/**
* @interface IComputeCallbacks
* @template T - Type extending IComputeData.
* @description Defines callback functions for compute lifecycle events.
*/
interface IComputeCallbacks<T extends IComputeData = IComputeData> {
/**
* @method onInit
* @description Called when the compute is initialized.
* @param {string} clientId - The client identifier.
* @param {ComputeName} computeName - The name of the compute.
*/
onInit: (clientId: string, computeName: ComputeName) => void;
/**
* @method onDispose
* @description Called when the compute is disposed.
* @param {string} clientId - The client identifier.
* @param {ComputeName} computeName - The name of the compute.
*/
onDispose: (clientId: string, computeName: ComputeName) => void;
/**
* @method onCompute
* @description Called when compute data is processed.
* @param {T} data - The computed data.
* @param {string} clientId - The client identifier.
* @param {ComputeName} computeName - The name of the compute.
*/
onCompute: (data: T, clientId: string, computeName: ComputeName) => void;
/**
* @method onCalculate
* @description Called when a recalculation is triggered by a state change.
* @param {StateName} stateName - The name of the state that changed.
* @param {string} clientId - The client identifier.
* @param {ComputeName} computeName - The name of the compute.
*/
onCalculate: (stateName: StateName, clientId: string, computeName: ComputeName) => void;
/**
* @method onUpdate
* @description Called when the compute is updated.
* @param {string} clientId - The client identifier.
* @param {ComputeName} computeName - The name of the compute.
*/
onUpdate: (clientId: string, computeName: ComputeName) => void;
}
/**
* @interface IComputeSchema
* @template T - Type extending IComputeData.
* @description Defines the schema for a compute, including its configuration and dependencies.
*/
interface IComputeSchema<T extends IComputeData = IComputeData> {
/**
* @property {string} [docDescription]
* @description Optional description for documentation purposes.
*/
docDescription?: string;
/**
* @property {boolean} [shared]
* @description Indicates if the compute is shared across clients.
*/
shared?: boolean;
/**
* @property {ComputeName} computeName
* @description The name of the compute.
*/
computeName: ComputeName;
/**
* @property {number} [ttl]
* @description Time-to-live for the compute data, in milliseconds.
*/
ttl?: number;
/**
* @property {Function} getComputeData
* @description Function to retrieve or compute the data.
* @param {string} clientId - The client identifier.
* @param {ComputeName} computeName - The name of the compute.
* @returns {T | Promise<T>} The computed data or a promise resolving to it.
*/
getComputeData: (clientId: string, computeName: ComputeName) => T | Promise<T>;
/**
* @property {StateName[]} [dependsOn]
* @description Array of state names the compute depends on.
*/
dependsOn?: StateName[];
/**
* @property {IComputeMiddleware<T>[]} [middlewares]
* @description Array of middleware functions to process compute data.
*/
middlewares?: IComputeMiddleware<T>[];
/**
* @property {Partial<IComputeCallbacks<T>>} [callbacks]
* @description Optional callbacks for compute lifecycle events.
*/
callbacks?: Partial<IComputeCallbacks<T>>;
}
/**
* @interface IComputeParams
* @template T - Type extending IComputeData.
* @extends IComputeSchema<T>
* @description Extends compute schema with additional parameters for compute initialization.
*/
interface IComputeParams<T extends IComputeData = IComputeData> extends IComputeSchema<T> {
/**
* @property {string} clientId
* @description The client identifier.
*/
clientId: string;
/**
* @property {ILogger} logger
* @description Logger instance for logging compute operations.
*/
logger: ILogger;
/**
* @property {IBus} bus
* @description Bus instance for event communication.
*/
bus: IBus;
/**
* @property {IStateChangeContract[]} binding
* @description Array of state change contracts for state dependencies.
*/
binding: IStateChangeContract[];
}
/**
* @interface ICompute
* @template T - Type extending IComputeData.
* @description Defines the contract for compute operations.
*/
interface ICompute<T extends IComputeData = IComputeData> {
/**
* @method calculate
* @description Triggers a recalculation based on a state change.
* @param {StateName} stateName - The name of the state that changed.
* @returns {Promise<void>} Resolves when the calculation is complete.
*/
calculate: (stateName: StateName) => Promise<void>;
/**
* @method update
* @description Forces an update of the compute instance.
* @param {string} clientId - The client identifier.
* @param {ComputeName} computeName - The name of the compute.
* @returns {Promise<void>} Resolves when the update is complete.
*/
update: (clientId: string, computeName: ComputeName) => Promise<void>;
/**
* @method getComputeData
* @description Retrieves the computed data.
* @returns {T | Promise<T>} The computed data or a promise resolving to it.
*/
getComputeData: () => T | Promise<T>;
}
/**
* @typedef {string} ComputeName
* @description Type alias for the compute name, represented as a string.
*/
type ComputeName = string;
/**
* Interface representing the contextual metadata for an event in the swarm system.
* Provides optional identifiers for components involved in an event (e.g., agent, swarm, storage), used partially in IBusEvent.context to supply additional context.
* In ClientAgent, typically only agentName is populated (e.g., context: { agentName }), with other fields available for broader system use (e.g., swarm or policy events).
*/
interface IBusEventContext {
/**
* The unique name of the agent associated with the event.
* Links the event to a specific agent instance (e.g., this.params.agentName in ClientAgent), consistently included in IBusEvent.context.
* Example: "Agent1" for an agent emitting a "run" event.
* @type {AgentName}
*/
agentName: AgentName;
/**
* The unique name of the swarm associated with the event.
* Identifies the swarm context, potentially used in swarm-wide events (e.g., IBus.emit in ISwarmParams), though not observed in ClientAgent.
* Example: "SwarmA" for a swarm-level navigation event.
* @type {SwarmName}
*/
swarmName: SwarmName;
/**
* The unique name of the storage associated with the event.
* Ties the event to a specific storage instance (e.g., IStorage), potentially for storage-related events, unused in ClientAgent’s agent-centric emissions.
* Example: "Storage1" for a storage upsert event.
* @type {StorageName}
*/
storageName: StorageName;
/**
* The unique name of the state associated with the event.
* Links to a specific state instance (e.g., IState), potentially for state change events, not populated in ClientAgent’s context.
* Example: "StateX" for a state update event.
* @type {StateName}
*/
stateName: StateName;
/**
* The unique name of the compute associated with the event.
* Links to a specific compute instance (e.g., ICompute), potentially for compute events, not populated in ClientAgent’s context.
* Example: "ComputeX" for a compute update event.
* @type {ComputeName}
*/
computeName: ComputeName;
/**
* The unique name of the policy associated with the event.
* Identifies the policy context (e.g., IPolicy), potentially for policy enforcement events (e.g., bans), unused in ClientAgent’s emissions.
* Example: "PolicyY" for a client ban event.
* @type {PolicyName}
*/
policyName: PolicyName;
}
/**
* Type representing the possible sources of an event in the swarm system.
* A generic string identifier for the event’s origin, used in IBaseEvent.source and overridden by EventBusSource in IBusEvent for specific bus-related sources.
* Example: "custom-source" for a generic event, though typically refined by EventBusSource in practice.
* @typedef {string} EventSource
*/
type EventSource =