@artinet/sdk
Version:
A TypeScript SDK for building collaborative AI agents.
78 lines (77 loc) • 2.78 kB
JavaScript
/**
* Copyright 2025 The Artinet Project
* SPDX-License-Identifier: Apache-2.0
*/
import { InMemoryPushNotificationStore, } from "@a2a-js/sdk/server";
import { Manager } from "../../services/core/manager.js";
/** Cached Push Notifications Manager */
export class PushNotifications
//May be more efficient to use a Record/Map instead of an array
extends Manager {
_store;
_sender;
constructor(store, sender) {
if (store && store instanceof InMemoryPushNotificationStore) {
/** We snatch its internal store to avoid creating a new Map and doubling memory usage */
super(store?.store);
}
else {
super();
}
this._store = store;
this._sender = sender;
}
get store() {
return this._store;
}
get sender() {
return this._sender;
}
set sender(sender) {
this._sender = sender;
}
async save(taskId, pushNotificationConfig) {
pushNotificationConfig.id = pushNotificationConfig.id ?? taskId;
/** Cache the configs in memory for faster access */
const configs = await this.get(taskId);
await this.set(taskId, [
...(configs?.filter(
/**
* Since this is pure memory we can stomach the heavy filter operation for now,
* and its unlikely that an individual task will have excessive configs.
* @note Consider adding a warning when the filter operation is called with a large number of configs.
*/
(config) => config.id !== pushNotificationConfig.id) ?? []),
pushNotificationConfig,
]);
return await this.store?.save(taskId, pushNotificationConfig);
}
async load(taskId) {
let configs = await this.get(taskId);
/**
* Cache the configs in memory for faster access regardless of the storage layer.
* @note this may be removed once we have a persistant storage layer plugin.
*/
if (!configs || configs.length === 0) {
configs = await this.store?.load(taskId);
if (configs && configs.length > 0) {
await this.set(taskId, configs);
}
}
return configs ?? [];
}
async delete(taskId, configId) {
if (configId) {
await this.set(taskId, (await this.get(taskId))?.filter((config) => config.id !== configId) ??
[]);
}
else {
/**We dont need to maintain backward compatibility, so we can just delete all configs for the task*/
await super.delete(taskId);
}
await this.store?.delete(taskId, configId);
}
async send(task) {
return await this.sender?.send(task);
}
}