@snap-agent/core 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +286 -31
- package/dist/{chunk-Y5TTFQWC.mjs → chunk-FS7G3ID4.mjs} +4 -2
- package/dist/{index-CDsqnM8L.d.mts → index-m2vDW79n.d.mts} +59 -1
- package/dist/{index-CDsqnM8L.d.ts → index-m2vDW79n.d.ts} +59 -1
- package/dist/index.d.mts +153 -7
- package/dist/index.d.ts +153 -7
- package/dist/index.js +236 -8
- package/dist/index.mjs +230 -8
- package/dist/storage/index.d.mts +1 -1
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.js +4 -2
- package/dist/storage/index.mjs +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -7327,12 +7327,16 @@ __export(index_exports, {
|
|
|
7327
7327
|
Models: () => Models,
|
|
7328
7328
|
MongoDBStorage: () => MongoDBStorage,
|
|
7329
7329
|
PluginManager: () => PluginManager,
|
|
7330
|
+
PluginRegistry: () => PluginRegistry,
|
|
7330
7331
|
ProviderFactory: () => ProviderFactory,
|
|
7331
7332
|
ProviderNotFoundError: () => ProviderNotFoundError,
|
|
7332
7333
|
Thread: () => Thread,
|
|
7333
7334
|
ThreadNotFoundError: () => ThreadNotFoundError,
|
|
7334
7335
|
UpstashStorage: () => UpstashStorage,
|
|
7335
|
-
createClient: () => createClient
|
|
7336
|
+
createClient: () => createClient,
|
|
7337
|
+
envRef: () => envRef,
|
|
7338
|
+
pluginRegistry: () => pluginRegistry,
|
|
7339
|
+
resolveEnvVars: () => resolveEnvVars
|
|
7336
7340
|
});
|
|
7337
7341
|
module.exports = __toCommonJS(index_exports);
|
|
7338
7342
|
|
|
@@ -7551,33 +7555,88 @@ var Agent = class _Agent {
|
|
|
7551
7555
|
}
|
|
7552
7556
|
/**
|
|
7553
7557
|
* Create a new agent
|
|
7558
|
+
*
|
|
7559
|
+
* If plugins are provided, their configurations will be extracted (if they implement getConfig())
|
|
7560
|
+
* and stored in the database for later reinstantiation.
|
|
7554
7561
|
*/
|
|
7555
7562
|
static async create(config, storage, providerFactory) {
|
|
7556
|
-
const
|
|
7563
|
+
const pluginConfigs = config.pluginConfigs || [];
|
|
7564
|
+
if (config.plugins && config.plugins.length > 0) {
|
|
7565
|
+
for (const plugin of config.plugins) {
|
|
7566
|
+
if ("getConfig" in plugin && typeof plugin.getConfig === "function") {
|
|
7567
|
+
pluginConfigs.push({
|
|
7568
|
+
type: plugin.type,
|
|
7569
|
+
name: plugin.name,
|
|
7570
|
+
config: plugin.getConfig(),
|
|
7571
|
+
priority: plugin.priority,
|
|
7572
|
+
enabled: true
|
|
7573
|
+
});
|
|
7574
|
+
}
|
|
7575
|
+
}
|
|
7576
|
+
}
|
|
7577
|
+
const configWithPluginConfigs = {
|
|
7578
|
+
...config,
|
|
7579
|
+
pluginConfigs
|
|
7580
|
+
};
|
|
7581
|
+
const agentId = await storage.createAgent(configWithPluginConfigs);
|
|
7557
7582
|
const data = await storage.getAgent(agentId);
|
|
7558
7583
|
if (!data) {
|
|
7559
7584
|
throw new AgentNotFoundError(agentId);
|
|
7560
7585
|
}
|
|
7586
|
+
data.plugins = config.plugins || [];
|
|
7561
7587
|
return new _Agent(data, storage, providerFactory);
|
|
7562
7588
|
}
|
|
7563
7589
|
/**
|
|
7564
7590
|
* Load an existing agent by ID
|
|
7591
|
+
*
|
|
7592
|
+
* Plugins can be attached in three ways (in order of priority):
|
|
7593
|
+
* 1. Direct plugins array - runtime plugin instances passed directly
|
|
7594
|
+
* 2. Plugin registry - reinstantiate from stored configs using registered factories
|
|
7595
|
+
* 3. No plugins - agent loads without plugin functionality
|
|
7596
|
+
*
|
|
7597
|
+
* @param agentId - The agent ID to load
|
|
7598
|
+
* @param storage - Storage adapter
|
|
7599
|
+
* @param providerFactory - Provider factory
|
|
7600
|
+
* @param options - Either:
|
|
7601
|
+
* - Plugin[] array (legacy, for backwards compatibility)
|
|
7602
|
+
* - Options object with plugins and/or registry
|
|
7565
7603
|
*/
|
|
7566
|
-
static async load(agentId, storage, providerFactory) {
|
|
7604
|
+
static async load(agentId, storage, providerFactory, options) {
|
|
7567
7605
|
const data = await storage.getAgent(agentId);
|
|
7568
7606
|
if (!data) {
|
|
7569
7607
|
return null;
|
|
7570
7608
|
}
|
|
7609
|
+
if (Array.isArray(options)) {
|
|
7610
|
+
data.plugins = options;
|
|
7611
|
+
return new _Agent(data, storage, providerFactory);
|
|
7612
|
+
}
|
|
7613
|
+
if (options?.plugins && options.plugins.length > 0) {
|
|
7614
|
+
data.plugins = options.plugins;
|
|
7615
|
+
} else if (options?.registry && data.pluginConfigs && data.pluginConfigs.length > 0) {
|
|
7616
|
+
try {
|
|
7617
|
+
data.plugins = await options.registry.instantiateAll(data.pluginConfigs);
|
|
7618
|
+
} catch (error) {
|
|
7619
|
+
console.error("Failed to reinstantiate plugins from stored configs:", error);
|
|
7620
|
+
throw error;
|
|
7621
|
+
}
|
|
7622
|
+
} else {
|
|
7623
|
+
data.plugins = [];
|
|
7624
|
+
}
|
|
7571
7625
|
return new _Agent(data, storage, providerFactory);
|
|
7572
7626
|
}
|
|
7573
7627
|
/**
|
|
7574
7628
|
* Update agent properties
|
|
7575
7629
|
*/
|
|
7576
7630
|
async update(updates) {
|
|
7631
|
+
const currentPlugins = this.data.plugins || [];
|
|
7577
7632
|
await this.storage.updateAgent(this.data.id, updates);
|
|
7578
7633
|
const updatedData = await this.storage.getAgent(this.data.id);
|
|
7579
7634
|
if (updatedData) {
|
|
7635
|
+
updatedData.plugins = updates.plugins || currentPlugins;
|
|
7580
7636
|
this.data = updatedData;
|
|
7637
|
+
if (updates.plugins) {
|
|
7638
|
+
this.pluginManager = new PluginManager(updatedData.plugins);
|
|
7639
|
+
}
|
|
7581
7640
|
}
|
|
7582
7641
|
}
|
|
7583
7642
|
/**
|
|
@@ -8390,6 +8449,7 @@ var AgentClient = class {
|
|
|
8390
8449
|
this.storage = config.storage;
|
|
8391
8450
|
this.providers = config.providers;
|
|
8392
8451
|
this.providerFactory = new ProviderFactory(config.providers);
|
|
8452
|
+
this.pluginRegistry = config.pluginRegistry;
|
|
8393
8453
|
}
|
|
8394
8454
|
validateConfig(config) {
|
|
8395
8455
|
if (!config.storage) {
|
|
@@ -8432,9 +8492,28 @@ var AgentClient = class {
|
|
|
8432
8492
|
}
|
|
8433
8493
|
/**
|
|
8434
8494
|
* Get an agent by ID
|
|
8495
|
+
*
|
|
8496
|
+
* Plugin loading priority:
|
|
8497
|
+
* 1. Direct plugins array passed to this method
|
|
8498
|
+
* 2. Plugin registry (if configured) - reinstantiates from stored configs
|
|
8499
|
+
* 3. No plugins
|
|
8500
|
+
*
|
|
8501
|
+
* @param agentId - The agent ID to load
|
|
8502
|
+
* @param options - Either Plugin[] for backwards compatibility, or options object
|
|
8435
8503
|
*/
|
|
8436
|
-
async getAgent(agentId) {
|
|
8437
|
-
|
|
8504
|
+
async getAgent(agentId, options) {
|
|
8505
|
+
if (Array.isArray(options)) {
|
|
8506
|
+
const agent2 = await Agent.load(agentId, this.storage, this.providerFactory, options);
|
|
8507
|
+
if (!agent2) {
|
|
8508
|
+
throw new AgentNotFoundError(agentId);
|
|
8509
|
+
}
|
|
8510
|
+
return agent2;
|
|
8511
|
+
}
|
|
8512
|
+
const registry = options?.registry || this.pluginRegistry;
|
|
8513
|
+
const agent = await Agent.load(agentId, this.storage, this.providerFactory, {
|
|
8514
|
+
plugins: options?.plugins,
|
|
8515
|
+
registry
|
|
8516
|
+
});
|
|
8438
8517
|
if (!agent) {
|
|
8439
8518
|
throw new AgentNotFoundError(agentId);
|
|
8440
8519
|
}
|
|
@@ -8592,6 +8671,149 @@ Return only the title without additional explanations.`
|
|
|
8592
8671
|
}
|
|
8593
8672
|
};
|
|
8594
8673
|
|
|
8674
|
+
// src/core/PluginRegistry.ts
|
|
8675
|
+
function resolveEnvVars(config) {
|
|
8676
|
+
const resolved = {};
|
|
8677
|
+
for (const [key, value] of Object.entries(config)) {
|
|
8678
|
+
if (typeof value === "string") {
|
|
8679
|
+
const envMatch = value.match(/^\$\{([^}:]+)(?::([^}]*))?\}$/);
|
|
8680
|
+
if (envMatch) {
|
|
8681
|
+
const [, envVar, defaultValue] = envMatch;
|
|
8682
|
+
const envValue = process.env[envVar];
|
|
8683
|
+
if (envValue !== void 0) {
|
|
8684
|
+
resolved[key] = envValue;
|
|
8685
|
+
} else if (defaultValue !== void 0) {
|
|
8686
|
+
resolved[key] = defaultValue;
|
|
8687
|
+
} else {
|
|
8688
|
+
throw new Error(
|
|
8689
|
+
`Environment variable ${envVar} is required for plugin config but not set`
|
|
8690
|
+
);
|
|
8691
|
+
}
|
|
8692
|
+
} else {
|
|
8693
|
+
resolved[key] = value;
|
|
8694
|
+
}
|
|
8695
|
+
} else if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
8696
|
+
resolved[key] = resolveEnvVars(value);
|
|
8697
|
+
} else {
|
|
8698
|
+
resolved[key] = value;
|
|
8699
|
+
}
|
|
8700
|
+
}
|
|
8701
|
+
return resolved;
|
|
8702
|
+
}
|
|
8703
|
+
var PluginRegistry = class {
|
|
8704
|
+
constructor() {
|
|
8705
|
+
this.registrations = /* @__PURE__ */ new Map();
|
|
8706
|
+
}
|
|
8707
|
+
/**
|
|
8708
|
+
* Register a plugin factory
|
|
8709
|
+
*
|
|
8710
|
+
* @param name - Unique plugin identifier (e.g., "@snap-agent/rag-ecommerce")
|
|
8711
|
+
* @param factory - Function that creates plugin instance from config
|
|
8712
|
+
* @param defaultConfig - Optional default configuration values
|
|
8713
|
+
*/
|
|
8714
|
+
register(name14, factory6, defaultConfig) {
|
|
8715
|
+
if (this.registrations.has(name14)) {
|
|
8716
|
+
console.warn(`Plugin "${name14}" is already registered. Overwriting.`);
|
|
8717
|
+
}
|
|
8718
|
+
this.registrations.set(name14, { factory: factory6, defaultConfig });
|
|
8719
|
+
}
|
|
8720
|
+
/**
|
|
8721
|
+
* Unregister a plugin factory
|
|
8722
|
+
*/
|
|
8723
|
+
unregister(name14) {
|
|
8724
|
+
return this.registrations.delete(name14);
|
|
8725
|
+
}
|
|
8726
|
+
/**
|
|
8727
|
+
* Check if a plugin is registered
|
|
8728
|
+
*/
|
|
8729
|
+
isRegistered(name14) {
|
|
8730
|
+
return this.registrations.has(name14);
|
|
8731
|
+
}
|
|
8732
|
+
/**
|
|
8733
|
+
* Get all registered plugin names
|
|
8734
|
+
*/
|
|
8735
|
+
getRegisteredPlugins() {
|
|
8736
|
+
return Array.from(this.registrations.keys());
|
|
8737
|
+
}
|
|
8738
|
+
/**
|
|
8739
|
+
* Instantiate a plugin from stored configuration
|
|
8740
|
+
*
|
|
8741
|
+
* @param storedConfig - Serialized plugin configuration from database
|
|
8742
|
+
* @returns Plugin instance
|
|
8743
|
+
* @throws Error if plugin is not registered
|
|
8744
|
+
*/
|
|
8745
|
+
async instantiate(storedConfig) {
|
|
8746
|
+
const registration = this.registrations.get(storedConfig.name);
|
|
8747
|
+
if (!registration) {
|
|
8748
|
+
throw new Error(
|
|
8749
|
+
`Plugin "${storedConfig.name}" is not registered. Available plugins: ${this.getRegisteredPlugins().join(", ") || "none"}. Make sure to register the plugin before loading the agent.`
|
|
8750
|
+
);
|
|
8751
|
+
}
|
|
8752
|
+
const mergedConfig = {
|
|
8753
|
+
...registration.defaultConfig,
|
|
8754
|
+
...storedConfig.config
|
|
8755
|
+
};
|
|
8756
|
+
const resolvedConfig = resolveEnvVars(mergedConfig);
|
|
8757
|
+
const plugin = await registration.factory(resolvedConfig);
|
|
8758
|
+
if (storedConfig.priority !== void 0) {
|
|
8759
|
+
plugin.priority = storedConfig.priority;
|
|
8760
|
+
}
|
|
8761
|
+
return plugin;
|
|
8762
|
+
}
|
|
8763
|
+
/**
|
|
8764
|
+
* Instantiate multiple plugins from stored configurations
|
|
8765
|
+
*
|
|
8766
|
+
* @param storedConfigs - Array of serialized plugin configurations
|
|
8767
|
+
* @returns Array of plugin instances (skips disabled plugins)
|
|
8768
|
+
*/
|
|
8769
|
+
async instantiateAll(storedConfigs) {
|
|
8770
|
+
const plugins = [];
|
|
8771
|
+
for (const config of storedConfigs) {
|
|
8772
|
+
if (config.enabled === false) {
|
|
8773
|
+
continue;
|
|
8774
|
+
}
|
|
8775
|
+
try {
|
|
8776
|
+
const plugin = await this.instantiate(config);
|
|
8777
|
+
plugins.push(plugin);
|
|
8778
|
+
} catch (error) {
|
|
8779
|
+
console.error(`Failed to instantiate plugin "${config.name}":`, error);
|
|
8780
|
+
throw error;
|
|
8781
|
+
}
|
|
8782
|
+
}
|
|
8783
|
+
return plugins;
|
|
8784
|
+
}
|
|
8785
|
+
/**
|
|
8786
|
+
* Extract serializable configuration from a plugin instance
|
|
8787
|
+
* Requires the plugin to implement getConfig() method
|
|
8788
|
+
*
|
|
8789
|
+
* @param plugin - Plugin instance
|
|
8790
|
+
* @returns Stored plugin configuration
|
|
8791
|
+
*/
|
|
8792
|
+
extractConfig(plugin) {
|
|
8793
|
+
const config = plugin.getConfig?.() ?? {};
|
|
8794
|
+
return {
|
|
8795
|
+
type: plugin.type,
|
|
8796
|
+
name: plugin.name,
|
|
8797
|
+
config,
|
|
8798
|
+
priority: plugin.priority,
|
|
8799
|
+
enabled: true
|
|
8800
|
+
};
|
|
8801
|
+
}
|
|
8802
|
+
/**
|
|
8803
|
+
* Extract configurations from multiple plugins
|
|
8804
|
+
*/
|
|
8805
|
+
extractAllConfigs(plugins) {
|
|
8806
|
+
return plugins.map((plugin) => this.extractConfig(plugin));
|
|
8807
|
+
}
|
|
8808
|
+
};
|
|
8809
|
+
var pluginRegistry = new PluginRegistry();
|
|
8810
|
+
function envRef(envVarName, defaultValue) {
|
|
8811
|
+
if (defaultValue !== void 0) {
|
|
8812
|
+
return `\${${envVarName}:${defaultValue}}`;
|
|
8813
|
+
}
|
|
8814
|
+
return `\${${envVarName}}`;
|
|
8815
|
+
}
|
|
8816
|
+
|
|
8595
8817
|
// src/storage/MongoDBStorage.ts
|
|
8596
8818
|
var import_mongodb = require("mongodb");
|
|
8597
8819
|
var MongoDBStorage = class {
|
|
@@ -8645,7 +8867,8 @@ var MongoDBStorage = class {
|
|
|
8645
8867
|
createdAt: /* @__PURE__ */ new Date(),
|
|
8646
8868
|
updatedAt: /* @__PURE__ */ new Date(),
|
|
8647
8869
|
files: [],
|
|
8648
|
-
metadata: config.metadata || {}
|
|
8870
|
+
metadata: config.metadata || {},
|
|
8871
|
+
pluginConfigs: config.pluginConfigs || []
|
|
8649
8872
|
};
|
|
8650
8873
|
const result = await collection.insertOne(doc);
|
|
8651
8874
|
return result.insertedId.toString();
|
|
@@ -8828,7 +9051,8 @@ var MongoDBStorage = class {
|
|
|
8828
9051
|
createdAt: doc.createdAt,
|
|
8829
9052
|
updatedAt: doc.updatedAt,
|
|
8830
9053
|
files: doc.files,
|
|
8831
|
-
metadata: doc.metadata
|
|
9054
|
+
metadata: doc.metadata,
|
|
9055
|
+
pluginConfigs: doc.pluginConfigs
|
|
8832
9056
|
};
|
|
8833
9057
|
}
|
|
8834
9058
|
threadDocToData(doc) {
|
|
@@ -9404,10 +9628,14 @@ function createClient(config) {
|
|
|
9404
9628
|
Models,
|
|
9405
9629
|
MongoDBStorage,
|
|
9406
9630
|
PluginManager,
|
|
9631
|
+
PluginRegistry,
|
|
9407
9632
|
ProviderFactory,
|
|
9408
9633
|
ProviderNotFoundError,
|
|
9409
9634
|
Thread,
|
|
9410
9635
|
ThreadNotFoundError,
|
|
9411
9636
|
UpstashStorage,
|
|
9412
|
-
createClient
|
|
9637
|
+
createClient,
|
|
9638
|
+
envRef,
|
|
9639
|
+
pluginRegistry,
|
|
9640
|
+
resolveEnvVars
|
|
9413
9641
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
MemoryStorage,
|
|
3
3
|
MongoDBStorage,
|
|
4
4
|
UpstashStorage
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-FS7G3ID4.mjs";
|
|
6
6
|
|
|
7
7
|
// src/core/Agent.ts
|
|
8
8
|
import { generateText, streamText } from "ai";
|
|
@@ -219,33 +219,88 @@ var Agent = class _Agent {
|
|
|
219
219
|
}
|
|
220
220
|
/**
|
|
221
221
|
* Create a new agent
|
|
222
|
+
*
|
|
223
|
+
* If plugins are provided, their configurations will be extracted (if they implement getConfig())
|
|
224
|
+
* and stored in the database for later reinstantiation.
|
|
222
225
|
*/
|
|
223
226
|
static async create(config, storage, providerFactory) {
|
|
224
|
-
const
|
|
227
|
+
const pluginConfigs = config.pluginConfigs || [];
|
|
228
|
+
if (config.plugins && config.plugins.length > 0) {
|
|
229
|
+
for (const plugin of config.plugins) {
|
|
230
|
+
if ("getConfig" in plugin && typeof plugin.getConfig === "function") {
|
|
231
|
+
pluginConfigs.push({
|
|
232
|
+
type: plugin.type,
|
|
233
|
+
name: plugin.name,
|
|
234
|
+
config: plugin.getConfig(),
|
|
235
|
+
priority: plugin.priority,
|
|
236
|
+
enabled: true
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const configWithPluginConfigs = {
|
|
242
|
+
...config,
|
|
243
|
+
pluginConfigs
|
|
244
|
+
};
|
|
245
|
+
const agentId = await storage.createAgent(configWithPluginConfigs);
|
|
225
246
|
const data = await storage.getAgent(agentId);
|
|
226
247
|
if (!data) {
|
|
227
248
|
throw new AgentNotFoundError(agentId);
|
|
228
249
|
}
|
|
250
|
+
data.plugins = config.plugins || [];
|
|
229
251
|
return new _Agent(data, storage, providerFactory);
|
|
230
252
|
}
|
|
231
253
|
/**
|
|
232
254
|
* Load an existing agent by ID
|
|
233
|
-
|
|
234
|
-
|
|
255
|
+
*
|
|
256
|
+
* Plugins can be attached in three ways (in order of priority):
|
|
257
|
+
* 1. Direct plugins array - runtime plugin instances passed directly
|
|
258
|
+
* 2. Plugin registry - reinstantiate from stored configs using registered factories
|
|
259
|
+
* 3. No plugins - agent loads without plugin functionality
|
|
260
|
+
*
|
|
261
|
+
* @param agentId - The agent ID to load
|
|
262
|
+
* @param storage - Storage adapter
|
|
263
|
+
* @param providerFactory - Provider factory
|
|
264
|
+
* @param options - Either:
|
|
265
|
+
* - Plugin[] array (legacy, for backwards compatibility)
|
|
266
|
+
* - Options object with plugins and/or registry
|
|
267
|
+
*/
|
|
268
|
+
static async load(agentId, storage, providerFactory, options) {
|
|
235
269
|
const data = await storage.getAgent(agentId);
|
|
236
270
|
if (!data) {
|
|
237
271
|
return null;
|
|
238
272
|
}
|
|
273
|
+
if (Array.isArray(options)) {
|
|
274
|
+
data.plugins = options;
|
|
275
|
+
return new _Agent(data, storage, providerFactory);
|
|
276
|
+
}
|
|
277
|
+
if (options?.plugins && options.plugins.length > 0) {
|
|
278
|
+
data.plugins = options.plugins;
|
|
279
|
+
} else if (options?.registry && data.pluginConfigs && data.pluginConfigs.length > 0) {
|
|
280
|
+
try {
|
|
281
|
+
data.plugins = await options.registry.instantiateAll(data.pluginConfigs);
|
|
282
|
+
} catch (error) {
|
|
283
|
+
console.error("Failed to reinstantiate plugins from stored configs:", error);
|
|
284
|
+
throw error;
|
|
285
|
+
}
|
|
286
|
+
} else {
|
|
287
|
+
data.plugins = [];
|
|
288
|
+
}
|
|
239
289
|
return new _Agent(data, storage, providerFactory);
|
|
240
290
|
}
|
|
241
291
|
/**
|
|
242
292
|
* Update agent properties
|
|
243
293
|
*/
|
|
244
294
|
async update(updates) {
|
|
295
|
+
const currentPlugins = this.data.plugins || [];
|
|
245
296
|
await this.storage.updateAgent(this.data.id, updates);
|
|
246
297
|
const updatedData = await this.storage.getAgent(this.data.id);
|
|
247
298
|
if (updatedData) {
|
|
299
|
+
updatedData.plugins = updates.plugins || currentPlugins;
|
|
248
300
|
this.data = updatedData;
|
|
301
|
+
if (updates.plugins) {
|
|
302
|
+
this.pluginManager = new PluginManager(updatedData.plugins);
|
|
303
|
+
}
|
|
249
304
|
}
|
|
250
305
|
}
|
|
251
306
|
/**
|
|
@@ -1058,6 +1113,7 @@ var AgentClient = class {
|
|
|
1058
1113
|
this.storage = config.storage;
|
|
1059
1114
|
this.providers = config.providers;
|
|
1060
1115
|
this.providerFactory = new ProviderFactory(config.providers);
|
|
1116
|
+
this.pluginRegistry = config.pluginRegistry;
|
|
1061
1117
|
}
|
|
1062
1118
|
validateConfig(config) {
|
|
1063
1119
|
if (!config.storage) {
|
|
@@ -1100,9 +1156,28 @@ var AgentClient = class {
|
|
|
1100
1156
|
}
|
|
1101
1157
|
/**
|
|
1102
1158
|
* Get an agent by ID
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1159
|
+
*
|
|
1160
|
+
* Plugin loading priority:
|
|
1161
|
+
* 1. Direct plugins array passed to this method
|
|
1162
|
+
* 2. Plugin registry (if configured) - reinstantiates from stored configs
|
|
1163
|
+
* 3. No plugins
|
|
1164
|
+
*
|
|
1165
|
+
* @param agentId - The agent ID to load
|
|
1166
|
+
* @param options - Either Plugin[] for backwards compatibility, or options object
|
|
1167
|
+
*/
|
|
1168
|
+
async getAgent(agentId, options) {
|
|
1169
|
+
if (Array.isArray(options)) {
|
|
1170
|
+
const agent2 = await Agent.load(agentId, this.storage, this.providerFactory, options);
|
|
1171
|
+
if (!agent2) {
|
|
1172
|
+
throw new AgentNotFoundError(agentId);
|
|
1173
|
+
}
|
|
1174
|
+
return agent2;
|
|
1175
|
+
}
|
|
1176
|
+
const registry = options?.registry || this.pluginRegistry;
|
|
1177
|
+
const agent = await Agent.load(agentId, this.storage, this.providerFactory, {
|
|
1178
|
+
plugins: options?.plugins,
|
|
1179
|
+
registry
|
|
1180
|
+
});
|
|
1106
1181
|
if (!agent) {
|
|
1107
1182
|
throw new AgentNotFoundError(agentId);
|
|
1108
1183
|
}
|
|
@@ -1260,6 +1335,149 @@ Return only the title without additional explanations.`
|
|
|
1260
1335
|
}
|
|
1261
1336
|
};
|
|
1262
1337
|
|
|
1338
|
+
// src/core/PluginRegistry.ts
|
|
1339
|
+
function resolveEnvVars(config) {
|
|
1340
|
+
const resolved = {};
|
|
1341
|
+
for (const [key, value] of Object.entries(config)) {
|
|
1342
|
+
if (typeof value === "string") {
|
|
1343
|
+
const envMatch = value.match(/^\$\{([^}:]+)(?::([^}]*))?\}$/);
|
|
1344
|
+
if (envMatch) {
|
|
1345
|
+
const [, envVar, defaultValue] = envMatch;
|
|
1346
|
+
const envValue = process.env[envVar];
|
|
1347
|
+
if (envValue !== void 0) {
|
|
1348
|
+
resolved[key] = envValue;
|
|
1349
|
+
} else if (defaultValue !== void 0) {
|
|
1350
|
+
resolved[key] = defaultValue;
|
|
1351
|
+
} else {
|
|
1352
|
+
throw new Error(
|
|
1353
|
+
`Environment variable ${envVar} is required for plugin config but not set`
|
|
1354
|
+
);
|
|
1355
|
+
}
|
|
1356
|
+
} else {
|
|
1357
|
+
resolved[key] = value;
|
|
1358
|
+
}
|
|
1359
|
+
} else if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
1360
|
+
resolved[key] = resolveEnvVars(value);
|
|
1361
|
+
} else {
|
|
1362
|
+
resolved[key] = value;
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
return resolved;
|
|
1366
|
+
}
|
|
1367
|
+
var PluginRegistry = class {
|
|
1368
|
+
constructor() {
|
|
1369
|
+
this.registrations = /* @__PURE__ */ new Map();
|
|
1370
|
+
}
|
|
1371
|
+
/**
|
|
1372
|
+
* Register a plugin factory
|
|
1373
|
+
*
|
|
1374
|
+
* @param name - Unique plugin identifier (e.g., "@snap-agent/rag-ecommerce")
|
|
1375
|
+
* @param factory - Function that creates plugin instance from config
|
|
1376
|
+
* @param defaultConfig - Optional default configuration values
|
|
1377
|
+
*/
|
|
1378
|
+
register(name, factory, defaultConfig) {
|
|
1379
|
+
if (this.registrations.has(name)) {
|
|
1380
|
+
console.warn(`Plugin "${name}" is already registered. Overwriting.`);
|
|
1381
|
+
}
|
|
1382
|
+
this.registrations.set(name, { factory, defaultConfig });
|
|
1383
|
+
}
|
|
1384
|
+
/**
|
|
1385
|
+
* Unregister a plugin factory
|
|
1386
|
+
*/
|
|
1387
|
+
unregister(name) {
|
|
1388
|
+
return this.registrations.delete(name);
|
|
1389
|
+
}
|
|
1390
|
+
/**
|
|
1391
|
+
* Check if a plugin is registered
|
|
1392
|
+
*/
|
|
1393
|
+
isRegistered(name) {
|
|
1394
|
+
return this.registrations.has(name);
|
|
1395
|
+
}
|
|
1396
|
+
/**
|
|
1397
|
+
* Get all registered plugin names
|
|
1398
|
+
*/
|
|
1399
|
+
getRegisteredPlugins() {
|
|
1400
|
+
return Array.from(this.registrations.keys());
|
|
1401
|
+
}
|
|
1402
|
+
/**
|
|
1403
|
+
* Instantiate a plugin from stored configuration
|
|
1404
|
+
*
|
|
1405
|
+
* @param storedConfig - Serialized plugin configuration from database
|
|
1406
|
+
* @returns Plugin instance
|
|
1407
|
+
* @throws Error if plugin is not registered
|
|
1408
|
+
*/
|
|
1409
|
+
async instantiate(storedConfig) {
|
|
1410
|
+
const registration = this.registrations.get(storedConfig.name);
|
|
1411
|
+
if (!registration) {
|
|
1412
|
+
throw new Error(
|
|
1413
|
+
`Plugin "${storedConfig.name}" is not registered. Available plugins: ${this.getRegisteredPlugins().join(", ") || "none"}. Make sure to register the plugin before loading the agent.`
|
|
1414
|
+
);
|
|
1415
|
+
}
|
|
1416
|
+
const mergedConfig = {
|
|
1417
|
+
...registration.defaultConfig,
|
|
1418
|
+
...storedConfig.config
|
|
1419
|
+
};
|
|
1420
|
+
const resolvedConfig = resolveEnvVars(mergedConfig);
|
|
1421
|
+
const plugin = await registration.factory(resolvedConfig);
|
|
1422
|
+
if (storedConfig.priority !== void 0) {
|
|
1423
|
+
plugin.priority = storedConfig.priority;
|
|
1424
|
+
}
|
|
1425
|
+
return plugin;
|
|
1426
|
+
}
|
|
1427
|
+
/**
|
|
1428
|
+
* Instantiate multiple plugins from stored configurations
|
|
1429
|
+
*
|
|
1430
|
+
* @param storedConfigs - Array of serialized plugin configurations
|
|
1431
|
+
* @returns Array of plugin instances (skips disabled plugins)
|
|
1432
|
+
*/
|
|
1433
|
+
async instantiateAll(storedConfigs) {
|
|
1434
|
+
const plugins = [];
|
|
1435
|
+
for (const config of storedConfigs) {
|
|
1436
|
+
if (config.enabled === false) {
|
|
1437
|
+
continue;
|
|
1438
|
+
}
|
|
1439
|
+
try {
|
|
1440
|
+
const plugin = await this.instantiate(config);
|
|
1441
|
+
plugins.push(plugin);
|
|
1442
|
+
} catch (error) {
|
|
1443
|
+
console.error(`Failed to instantiate plugin "${config.name}":`, error);
|
|
1444
|
+
throw error;
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
return plugins;
|
|
1448
|
+
}
|
|
1449
|
+
/**
|
|
1450
|
+
* Extract serializable configuration from a plugin instance
|
|
1451
|
+
* Requires the plugin to implement getConfig() method
|
|
1452
|
+
*
|
|
1453
|
+
* @param plugin - Plugin instance
|
|
1454
|
+
* @returns Stored plugin configuration
|
|
1455
|
+
*/
|
|
1456
|
+
extractConfig(plugin) {
|
|
1457
|
+
const config = plugin.getConfig?.() ?? {};
|
|
1458
|
+
return {
|
|
1459
|
+
type: plugin.type,
|
|
1460
|
+
name: plugin.name,
|
|
1461
|
+
config,
|
|
1462
|
+
priority: plugin.priority,
|
|
1463
|
+
enabled: true
|
|
1464
|
+
};
|
|
1465
|
+
}
|
|
1466
|
+
/**
|
|
1467
|
+
* Extract configurations from multiple plugins
|
|
1468
|
+
*/
|
|
1469
|
+
extractAllConfigs(plugins) {
|
|
1470
|
+
return plugins.map((plugin) => this.extractConfig(plugin));
|
|
1471
|
+
}
|
|
1472
|
+
};
|
|
1473
|
+
var pluginRegistry = new PluginRegistry();
|
|
1474
|
+
function envRef(envVarName, defaultValue) {
|
|
1475
|
+
if (defaultValue !== void 0) {
|
|
1476
|
+
return `\${${envVarName}:${defaultValue}}`;
|
|
1477
|
+
}
|
|
1478
|
+
return `\${${envVarName}}`;
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1263
1481
|
// src/index.ts
|
|
1264
1482
|
function createClient(config) {
|
|
1265
1483
|
return new AgentClient(config);
|
|
@@ -1275,10 +1493,14 @@ export {
|
|
|
1275
1493
|
Models,
|
|
1276
1494
|
MongoDBStorage,
|
|
1277
1495
|
PluginManager,
|
|
1496
|
+
PluginRegistry,
|
|
1278
1497
|
ProviderFactory,
|
|
1279
1498
|
ProviderNotFoundError,
|
|
1280
1499
|
Thread,
|
|
1281
1500
|
ThreadNotFoundError,
|
|
1282
1501
|
UpstashStorage,
|
|
1283
|
-
createClient
|
|
1502
|
+
createClient,
|
|
1503
|
+
envRef,
|
|
1504
|
+
pluginRegistry,
|
|
1505
|
+
resolveEnvVars
|
|
1284
1506
|
};
|
package/dist/storage/index.d.mts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { W as MemoryStorage, V as MongoDBStorage, Y as MongoDBStorageConfig, X as UpstashStorage, Z as UpstashStorageConfig } from '../index-m2vDW79n.mjs';
|
package/dist/storage/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { W as MemoryStorage, V as MongoDBStorage, Y as MongoDBStorageConfig, X as UpstashStorage, Z as UpstashStorageConfig } from '../index-m2vDW79n.js';
|
package/dist/storage/index.js
CHANGED
|
@@ -79,7 +79,8 @@ var MongoDBStorage = class {
|
|
|
79
79
|
createdAt: /* @__PURE__ */ new Date(),
|
|
80
80
|
updatedAt: /* @__PURE__ */ new Date(),
|
|
81
81
|
files: [],
|
|
82
|
-
metadata: config.metadata || {}
|
|
82
|
+
metadata: config.metadata || {},
|
|
83
|
+
pluginConfigs: config.pluginConfigs || []
|
|
83
84
|
};
|
|
84
85
|
const result = await collection.insertOne(doc);
|
|
85
86
|
return result.insertedId.toString();
|
|
@@ -262,7 +263,8 @@ var MongoDBStorage = class {
|
|
|
262
263
|
createdAt: doc.createdAt,
|
|
263
264
|
updatedAt: doc.updatedAt,
|
|
264
265
|
files: doc.files,
|
|
265
|
-
metadata: doc.metadata
|
|
266
|
+
metadata: doc.metadata,
|
|
267
|
+
pluginConfigs: doc.pluginConfigs
|
|
266
268
|
};
|
|
267
269
|
}
|
|
268
270
|
threadDocToData(doc) {
|