agent-swarm-kit
Version:
A TypeScript library for building orchestrated framework-agnostic multi-agent AI systems
1,064 lines (1,053 loc) • 724 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.
*/
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.
*/
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.
*/
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.
*/
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.
*/
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.
*/
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.
*/
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.
*/
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.
*/
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.
*/
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.
*/
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.
*/
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.
* @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).
* @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.
* @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.
* @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.
* Used to identify and reference specific embedding implementations.
*/
type EmbeddingName = string;
/**
* Type representing the unique identifier for storage items.
* Can be either a string or number for flexible item identification.
*/
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.
*/
getData?: (clientId: string, storageName: StorageName, defaultValue: T[]) => Promise<T[]> | T[];
/**
* Optional function to persist storage data to the hard drive, overriding default behavior.
* @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.
*/
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.
*/
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.
*/
onUpdate: (items: T[], clientId: string, storageName: StorageName) => void;
/**
* Callback triggered during a search operation on 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.
*/
onInit: (clientId: string, storageName: StorageName) => void;
/**
* Callback triggered when the storage is disposed of.
* Useful for cleanup or logging.
*/
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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
* Used to identify and reference specific storage instances.
*/
type StorageName = string;
/**
* Type representing the data structure of a state.
* Can be any type, serving as a generic placeholder for state values.
*/
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.
* @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.
*/
onInit: (clientId: string, stateName: StateName) => void;
/**
* Callback triggered when the state is disposed of.
* Useful for cleanup or logging.
*/
onDispose: (clientId: string, stateName: StateName) => void;
/**
* Callback triggered when the state is loaded from storage or initialized.
*/
onLoad: (state: T, clientId: string, stateName: StateName) => void;
/**
* Callback triggered when the state is read.
* Useful for monitoring or logging read operations.
*/
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.
*/
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.
*/
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.
*/
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.
* @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.
* @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.
* @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.
* @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.
* Used to identify and reference specific state instances.
*/
type StateName = string;
/**
* Interface for handling state change events using a subject pattern.
* Provides a subject to subscribe to state updates.
*/
interface IStateChangeEvent {
/**
* A subject that emits state names when changes occur, allowing subscribers to react to state updates.
* Provides reactive state change notifications throughout the system.
*/
stateChanged: TSubject<StateName>;
}
/**
* 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.
*/
onInit?: (policyName: PolicyName) => void;
/**
* Optional callback triggered to validate incoming messages.
* Useful for logging or monitoring input validation.
*/
onValidateInput?: (incoming: string, clientId: SessionId, swarmName: SwarmName, policyName: PolicyName) => void;
/**
* Optional callback triggered to validate outgoing messages.
* Useful for logging or monitoring output validation.
*/
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.
*/
onBanClient?: (clientId: SessionId, swarmName: SwarmName, policyName: PolicyName) => void;
/**
* Optional callback triggered when a client is unbanned.
* Useful for logging or triggering unban-related actions.
*/
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.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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.
*/
getBanMessage?: (clientId: SessionId, policyName: PolicyName, swarmName: SwarmName) => Promise<string | null> | string | null;
/**
* Retrieves the list of currently banned clients under this policy.
*/
getBannedClients?: (policyName: PolicyName, swarmName: SwarmName) => SessionId[] | Promise<SessionId[]>;
/**
* Optional function to set the list of banned clients.
* Overrides default ban list management if provided.
* @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.
*/
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.
*/
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.
* Used to identify and reference specific policy implementations.
*/
type PolicyName = string;
/**
* @module ComputeInterface
* Defines interfaces and types for compute-related operations, including schemas, middleware, callbacks, and contracts.
*/
/**
* Generic type for compute data, allowing flexibility in data structure.
* Can be any type to support diverse compute operations.
*/
type IComputeData = any;
/**
* @interface IComputeMiddleware
* @template T - Type extending IComputeData.
* Defines a middleware function for processing compute data.
*/
interface IComputeMiddleware<T extends IComputeData = IComputeData> {
/**
*/
(state: T, clientId: string, computeName: ComputeName): Promise<T>;
}
/**
* @interface IComputeCallbacks
* @template T - Type extending IComputeData.
* Defines callback functions for compute lifecycle events.
*/
interface IComputeCallbacks<T extends IComputeData = IComputeData> {
/**
* @method onInit
* Called when the compute is initialized.
*/
onInit: (clientId: string, computeName: ComputeName) => void;
/**
* @method onDispose
* Called when the compute is disposed.
*/
onDispose: (clientId: string, computeName: ComputeName) => void;
/**
* @method onCompute
* Called when compute data is processed.
*/
onCompute: (data: T, clientId: string, computeName: ComputeName) => void;
/**
* @method onCalculate
* Called when a recalculation is triggered by a state change.
*/
onCalculate: (stateName: StateName, clientId: string, computeName: ComputeName) => void;
/**
* Called when the compute is updated.
* Triggered whenever compute data or configuration changes, allowing for reactive updates.
*/
onUpdate: (clientId: string, computeName: ComputeName) => void;
}
/**
* @interface IComputeSchema
* @template T - Type extending IComputeData.
* Defines the schema for a compute, including its configuration and dependencies.
*/
interface IComputeSchema<T extends IComputeData = IComputeData> {
/**
* @property {string} [docDescription]
* Optional description for documentation purposes.
*/
docDescription?: string;
/**
* @property {boolean} [shared]
* Indicates if the compute is shared across clients.
*/
shared?: boolean;
/**
* @property {ComputeName} computeName
* The name of the compute.
*/
computeName: ComputeName;
/**
* @property {number} [ttl]
* Time-to-live for the compute data, in milliseconds.
*/
ttl?: number;
/**
* @property {Function} getComputeData
* Function to retrieve or compute the data.
*/
getComputeData: (clientId: string, computeName: ComputeName) => T | Promise<T>;
/**
* @property {StateName[]} [dependsOn]
* Array of state names the compute depends on.
*/
dependsOn?: StateName[];
/**
* @property {IComputeMiddleware<T>[]} [middlewares]
* Array of middleware functions to process compute data.
*/
middlewares?: IComputeMiddleware<T>[];
/**
* Optional callbacks for compute lifecycle events.
* Provides hooks for handling compute updates, data changes, and other lifecycle events.
*/
callbacks?: Partial<IComputeCallbacks<T>>;
}
/**
* @interface IComputeParams
* @template T - Type extending IComputeData.
* @extends IComputeSchema<T>
* Extends compute schema with additional parameters for compute initialization.
*/
interface IComputeParams<T extends IComputeData = IComputeData> extends IComputeSchema<T> {
/**
* @property {string} clientId
* The client identifier.
*/
clientId: string;
/**
* @property {ILogger} logger
* Logger instance for logging compute operations.
*/
logger: ILogger;
/**
* @property {IBus} bus
* Bus instance for event communication.
*/
bus: IBus;
/**
* Array of state change contracts for state dependencies.
* Defines which state changes trigger compute recalculation and data updates.
*/
binding: IStateChangeEvent[];
}
/**
* @interface ICompute
* @template T - Type extending IComputeData.
* Defines the contract for compute operations.
*/
interface ICompute<T extends IComputeData = IComputeData> {
/**
* @method calculate
* Triggers a recalculation based on a state change.
*/
calculate: (stateName: StateName) => Promise<void>;
/**
* @method update
* Forces an update of the compute instance.
*/
update: (clientId: string, computeName: ComputeName) => Promise<void>;
/**
* Retrieves the computed data.
* Returns the current result of the compute operation, either synchronously or asynchronously.
*/
getComputeData: () => T | Promise<T>;
}
/**
* Type alias for the compute name, represented as a string.
* Used to identify and reference specific compute instances.
*/
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.
*/
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.
*/
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.
*/
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.
*/
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.
*/
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.
*/
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.
*/
type EventSource = string;
/**
* Type representing specific sources of events for the internal bus in the swarm system.
* Enumerates predefined origins for IBusEvent.source, observed as "agent-bus" in ClientAgent (e.g., bus.emit calls), with other values likely used in corresponding components (e.g., "history-bus" in IHistory).
*/
type EventBusSource = "agent-bus" | "history-bus" | "session-bus" | "state-bus" | "storage-bus" | "swarm-bus" | "execution-bus" | "policy-bus" | "compute-bus";
/**
* Interface representing the base structure of an event in the swarm system.
* Defines the minimal required fields for all events, extended by IBusEvent and ICustomEvent for specific use cases, and used generically in IBus.emit<T>.
* Provides a foundation for event-driven communication across components like agents, sessions, and swarms.
*/
interface IBaseEvent {
/**
* The source of the event, identifying its origin within the system.
* A generic string (EventSource) in IBaseEvent, overridden by EventBusSource in IBusEvent (e.g., "agent-bus" in ClientAgent).
* Example: "custom-source" for a basic event, or "agent-bus" in practice.
*/
source: EventSource;
/**
* The unique identifier of the client targeted by the event.
* Matches the clientId used in runtime params (e.g., this.params.clientId in ClientAgent), ensuring events reach the intended session or agent instance.
* Example: "client-123" for a user session receiving an "emit-output" event.
*/
clientId: string;
}
/**
* Interface representing a structured event for the internal bus in the swarm system.
* Extends IBaseEvent with a specific schema, used extensively in ClientAgent’s bus.emit calls (e.g., "run", "commit-user-message") to notify the system of actions, outputs, or state changes.
* Dispatched via IBus.emit<IBusEvent> to broadcast detailed, agent-driven events with input/output data and context.
*/
interface IBusEvent extends Omit<IBaseEvent, keyof {
source: never;
}> {
/**
* The specific source of the event, restricted to EventBusSource values.
* Identifies the component emitting the event, consistently "agent-bus" in ClientAgent (e.g., RUN_FN, _emitOutput), with other values for other buses (e.g., "history-bus").
* Example: "agent-bus" for an agent’s "emit-output" event.
*/
source: EventBusSource;
/**
* The type of the event, defining its purpose or action.
* A string identifier unique to the event’s intent, observed in ClientAgent as "run", "emit-output", "commit-user-message", etc.
* Example: "commit-tool-output" for a tool execution result.
*/
type: string;
/**
* The input data for the event, as a key-value object.
* Carries event-specific input (e.g., { message } in "commit-user-message", { mode, rawResult } in "emit-output" from ClientAgent), often tied to ISwarmMessage content.
* Example: { toolId: "tool-xyz", content: "result" } for a tool output event.
*/
input: Record<string, any>;
/**
* The output data for the event, as a key-value object.
* Contains event-specific results (e.g., { result } in "run" or "emit-output" from ClientAgent), often empty {} for notifications (e.g., "commit-flush").
* Example: { result: "processed data" } for an execution output.
*/
output: Record<string, any>;
/**
* The contextual metadata for the event, partially implementing IBusEventContext.
* Typically includes only agentName in ClientAgent (e.g., { agentName: this.params.agentName }), with other fields optional for broader use cases.
* Example: { agentName: "Agent1" } for an agent-driven event.
*/
context: Partial<IBusEventContext>;
}
/**
* Interface representing a custom event with a flexible payload in the swarm system.
* Extends IBaseEvent for generic event handling, allowing arbitrary data via payload, though not directly observed in ClientAgent (which uses IBusEvent).
* Likely used for bespoke event scenarios outside the structured IBusEvent schema, dispatched via IBus.emit<ICustomEvent>.
*/
interface ICustomEvent<T extends any = any> extends IBaseEvent {
/**
* The optional payload of the event, carrying custom data of any type.
* Provides flexibility for event-specific information, unlike IBusEvent’s rigid input/output structure, potentially for user-defined events.
* Example: { status: "complete", data: 42 } for a custom completion event.
*/
payload?: T;
}
/**
* Interface representing an event bus for the swarm system.
* Provides a mechanism for asynchronous, client-targeted event dispatching, primarily used by agents (e.g., ClientAgent) to broadcast operational updates, lifecycle changes, and outputs to the system.
* Integrated into runtime parameters (e.g., IAgentParams, ISessionParams), the bus ensures decoupled communication between components, such as notifying clients of message commits, tool outputs, or execution results.
*/
interface IBus {
/**
* Emits a structured event to a specific client within the swarm system.
* Asynchronously dispatches events to the designated `clientId`, enabling agents to notify the system of actions like message commits, tool executions, or output emissions.
* Events follow a consistent schema extending IBaseEvent, including `type` (event identifier), `source` (originator, typically "agent-bus"), `input` (input data), `output` (result data), `context` (metadata with agentName), and `clientId` (redundant target ID).
*
* **Observed Behavior (from ClientAgent):**
* - **Event Dispatch**: Events are emitted after significant actions, such as completing a stateless run (`"run"`), emitting validated output (`"emit-output"`), or committing messages/tools (`"commit-*"`).
* - **Structure**: Every event includes a fixed set of fields, e.g.:
* ```javascript
* await this.params.bus.emit<IBusEvent>(this.params.clientId, {
* type: "commit-user-message",
* source: "agent-bus",
* input: { message },
* output: {},
* context: { agentName: this.params.agentName },
* clientId: this.params.clientId,
* });
* ```
* This notifies the system of a user message commit, with no output expected.
* - **Asynchronous Delivery**: Returns a promise, implying events are queued or sent over a channel (e.g., network, in-memory queue), resolving when dispatched.
* - **Client Targeting**: Always targets the client’s session ID (e.g., `this.params.clientId`), ensuring precise delivery to the intended recipient.
* - **Notification Focus**: Primarily used for one-way notifications (e.g., history updates, tool stops), with `output` often empty unless carrying results (e.g., `"run"`, `"emit-output"`).
*
* **Example Usage in ClientAgent:**
* - **Stateless Completion**:
* ```javascript
* await this.params.bus.emit<IBusEvent>(this.params.clientId, {
* type: "run",
* source: "agent-bus",
* input: { message },
* output: { result },
* context: { agentName: this.params.agentName },
* clientId: this.params.clientId,
* });
* ```
* Signals a completed stateless run with the transformed result.
* - **Output Emission**:
* ```javascript
* await this.params.bus.emit<IBusEvent>(this.params.clientId, {
* type: "emit-output",
* source: "agent-bus",
* input: { mode, rawResult },
* output: { result },
* context: { agentName: this.params.agentName },
* clientId: this.params.clientId,
* });
* ```
* Broadcasts the final output after validation.
*
* **Key Characteristics:**
* - **Redundancy**: The `clientId` in the event mirrors the emit target, aiding downstream filtering or validation.
* - **Type Safety**: Generic `<T>` ensures events conform to IBaseEvent extensions (e.g., IBusEvent), supporting structured payloads.
* - **Integration**: Paired with history updates (e.g., `history.push`) and callbacks (e.g., `onOutput`), amplifying system-wide awareness.
*
* @template T - The type of event, extending IBaseEvent, defining a structured payload with fields like `type`, `source`, `input`, `output`, `context`, and `clientId`.
* @throws {Error} If emission fails, potentially due to invalid `clientId`, malformed event structure, or delivery issues (e.g., queue overflow, network failure).
*/
emit<T extends IBaseEvent>(clientId: string, event: T): Promise<void>;
}
/**
* Interface representing callbacks for session-related events within a swarm.
* Provides hooks for connection, execution, and emission events.
*/
interface ISwarmSessionCallbacks {
/**
* Optional callback triggered when a client connects to the swarm.
* Useful for logging or initialization tasks.
*/
onConnect?: (clientId: string, swarmName: SwarmName) => void;
/**
* Optional callback triggered when a command is executed within the swarm.
*/
onExecute?: (clientId: string, swarmName: SwarmName, content: string, mode: ExecutionMode) => void;
/**
* Optional callback triggered when a stateless completion run is executed.
*/
onRun?: (clientId: string, swarmName: SwarmName, content: string) => void;
/**
* Optional callback triggered when a message is emitted from the swarm.
*/
onEmit?: (clientId: string, swarmName: SwarmName, message: string) => void;
/**
* Optional callback triggered when a session is initialized within the swarm.
*/
onInit?: (clientId: string, swarmName: SwarmName) => void;
/**
* Optional callback triggered when a session is disconnected or disposed of.
* Note: "disponnected" in original comment corrected to "disconnected".
*/
onDispose?: (clientId: string, swarmName: SwarmName) => void;
}
/**
* Interface representing lifecycle callbacks for an initialized swarm.
* Extends session callbacks with agent-specific navigation events.
* @extends {ISwarmSessionCallbacks}
*/
interface ISwarmCallbacks extends ISwarmSessionCallbacks {
/**
* Callback triggered when the active agent changes within the swarm.
* Useful for navigation tracking or state updates.
*/
onAgentChanged: (clientId: string, agentName: AgentName, swarmName: SwarmName) => Promise<void>;
}
/**
* Interface representing the parameters required to initialize a swarm.
* Extends the swarm schema (excluding certain fields) with runtime dependencies.
* @extends {Omit<ISwarmSchema, "agentList" | "onAgentChanged">}
*/
interface ISwarmParams extends Omit<ISwarmSchema, keyof {
agentList: never;
onAgentChanged: never;
}> {
/** The unique identifier of the client initializing the swarm.*/
clientId: string;
/** The logger instance for recording swarm-related activity and errors.*/
logger: ILogger;
/** The bus instance for event communication within the swarm.*/
bus: IBus;
/** A map of agent names to their corresponding agent instances for runtime access.*/
agentMap: Record<AgentName, IAgent>;
}
/**
* Interface representing the schema for defining a swarm.
* Configures the swarm's behavior, navigation, and agent management.
*/
interface ISwarmSchema {
/** Optional flag to enable serialization of navigation stack and active agent state to persistent storage (e.g., hard drive).*/
persist?: boolean;
/** Optional description for documentation purposes, aiding in swarm usage understanding.*/
docDescription?: string;
/** Optional array of policy names defining banhammer or access control rules for the swarm.*/
policies?: PolicyName[];
/**
* Optional function to retrieve the initial navigation stack after swarm initialization.
*/
getNavigationStack?: (clientId: string, swarmName: SwarmName) => Promise<AgentName[]> | AgentName[];
/**
* Optional function to persist the navigation stack after a change.
* @throws {Error} If persistence fails (e.g., due to storage issues).
*/
setNavigationStack?: (clientId: string, navigationStack: AgentName[], swarmName: SwarmName) => Promise<void>;
/**
* Optional function to fetch the active agent upon swarm initialization.
*/
getActiveAgent?: (clientId: string, swarmName: SwarmName, defaultAgent: AgentName) => Promise<AgentName> | AgentName;
/**
* Optional function to update the active agent after navigation changes.
* @throws {Error} If the update fails (e.g., due to persistence issues).
*/
setActiveAgent?: (clientId: string, agentName: AgentName, swarmName: SwarmName) => Promise<void> | void;
/** The default agent name to use when no active agent is specified.*/
defaultAgent: AgentName;
/** The unique name of the swarm within the system.*/
swarmName: string;
/** The list of agent names available within the swarm.*/
agentList: string[];
/** Optional partial set of lifecycle callbacks for the swarm, allowing customization of events.*/
callbacks?: Partial<ISwarmCallbacks>;
}
/**
* Interface representing a swarm of agents.
* Provides methods for navigation, agent management, and output handling.
*/
interface ISwarm {
/**
* Removes and returns the most recent agent from the navigation stack, or falls back to the default agent.
* @throws {Error} If navigation retrieval fails (e.g., due to persistence issues).
*/
navigationPop(): Promise<AgentName>;
/**
* Cancels the current output operation, resulting in an empty string from waitForOutput.
* @throws {Error} If cancellation fails (e.g., due to internal errors).
*/
cancelOutput(): Promise<void>;
/**
* Waits for and retrieves the output from the swarm’s active agent.
* @throws {Error} If no output is available or waiting times out.
*/
waitForOutput(): Promise<string>;
/**
* Retrieves the name of the currently active agent in the swarm.
* @throws {Error} If the active agent cannot be determined (e.g., due to persistence issues).
*/
getAgentName(): Promise<AgentName>;
/**
* Retrieves the instance of the currently active agent in the swarm.
* @throws {Error} If the agent instance cannot be retrieved (e.g., due to invalid agent name).
*/
getAgent(): Promise<IAgent>;
/**
* Registers or updates an agent reference in the swarm’s agent map.
* @throws {Error} If registration fails (e.g., due to invalid agent or internal errors).
*/
setAgentRef(agentName: AgentName, agent: IAgent): Promise<void>;
/**
* Sets the active agent in the swarm by name, updating navigation if applicable.
* @throws {Error} If setting the agent fails (e.g., due to persistence issues or invalid name).
*/
setAgentName(agentName: AgentName): Promise<void>;
/**
* Emits a message to the session's communication channel.
* @throws {Error} If the emission fails due to connection issues or invalid message format.
*/
emit(message: string): Promise<void>;
/**
* Returns the current busy state of the swarm.
* Used to check if the swarm is currently processing an operation (e.g., waiting for output or switching agents).
* Supports debugging and flow control in cli