@axiom-lattice/core 2.1.75 → 2.1.77
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 +340 -99
- package/dist/index.d.mts +558 -52
- package/dist/index.d.ts +558 -52
- package/dist/index.js +470 -96
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +468 -96
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -42,6 +42,7 @@ __export(index_exports, {
|
|
|
42
42
|
CompositeBackend: () => CompositeBackend,
|
|
43
43
|
ConsoleLoggerClient: () => ConsoleLoggerClient,
|
|
44
44
|
CustomMetricsClient: () => CustomMetricsClient,
|
|
45
|
+
CustomMiddlewareRegistry: () => CustomMiddlewareRegistry,
|
|
45
46
|
DaytonaInstance: () => DaytonaInstance,
|
|
46
47
|
DaytonaProvider: () => DaytonaProvider,
|
|
47
48
|
DefaultScheduleClient: () => DefaultScheduleClient,
|
|
@@ -115,6 +116,7 @@ __export(index_exports, {
|
|
|
115
116
|
checkEmptyContent: () => checkEmptyContent,
|
|
116
117
|
clearEncryptionKeyCache: () => clearEncryptionKeyCache,
|
|
117
118
|
computeSandboxName: () => computeSandboxName,
|
|
119
|
+
configureStores: () => configureStores,
|
|
118
120
|
createAgentTeam: () => createAgentTeam,
|
|
119
121
|
createExecuteSqlQueryTool: () => createExecuteSqlQueryTool,
|
|
120
122
|
createFileData: () => createFileData,
|
|
@@ -2546,24 +2548,6 @@ var InMemoryThreadMessageQueueStore = class {
|
|
|
2546
2548
|
}
|
|
2547
2549
|
}
|
|
2548
2550
|
}
|
|
2549
|
-
async markCompleted(messageId) {
|
|
2550
|
-
for (const messages of this.messages.values()) {
|
|
2551
|
-
const message = messages.find((msg) => msg.id === messageId);
|
|
2552
|
-
if (message) {
|
|
2553
|
-
message.status = "completed";
|
|
2554
|
-
return;
|
|
2555
|
-
}
|
|
2556
|
-
}
|
|
2557
|
-
}
|
|
2558
|
-
async clearCompletedMessages(threadId) {
|
|
2559
|
-
const messages = this.messages.get(threadId);
|
|
2560
|
-
if (messages) {
|
|
2561
|
-
const filtered = messages.filter(
|
|
2562
|
-
(msg) => msg.status !== "completed"
|
|
2563
|
-
);
|
|
2564
|
-
this.messages.set(threadId, filtered);
|
|
2565
|
-
}
|
|
2566
|
-
}
|
|
2567
2551
|
async resetProcessingToPending(threadId) {
|
|
2568
2552
|
const messages = this.messages.get(threadId);
|
|
2569
2553
|
if (!messages) {
|
|
@@ -2708,14 +2692,35 @@ var InMemoryChannelInstallationStore = class {
|
|
|
2708
2692
|
constructor() {
|
|
2709
2693
|
this.installations = /* @__PURE__ */ new Map();
|
|
2710
2694
|
}
|
|
2695
|
+
/**
|
|
2696
|
+
* Retrieves a channel installation by its unique ID.
|
|
2697
|
+
*
|
|
2698
|
+
* @param installationId - The installation identifier
|
|
2699
|
+
* @returns The {@link ChannelInstallation} or `null` if not found
|
|
2700
|
+
*/
|
|
2711
2701
|
async getInstallationById(installationId) {
|
|
2712
2702
|
return this.installations.get(installationId) || null;
|
|
2713
2703
|
}
|
|
2704
|
+
/**
|
|
2705
|
+
* Lists all channel installations for a tenant, optionally filtered by channel type.
|
|
2706
|
+
*
|
|
2707
|
+
* @param tenantId - Tenant identifier
|
|
2708
|
+
* @param channel - Optional channel type filter (`"lark"`, `"email"`, `"slack"`)
|
|
2709
|
+
* @returns Array of matching {@link ChannelInstallation} objects
|
|
2710
|
+
*/
|
|
2714
2711
|
async getInstallationsByTenant(tenantId, channel) {
|
|
2715
2712
|
return Array.from(this.installations.values()).filter(
|
|
2716
2713
|
(inst) => inst.tenantId === tenantId && (!channel || inst.channel === channel)
|
|
2717
2714
|
);
|
|
2718
2715
|
}
|
|
2716
|
+
/**
|
|
2717
|
+
* Creates a new channel installation for a tenant.
|
|
2718
|
+
*
|
|
2719
|
+
* @param tenantId - Tenant identifier
|
|
2720
|
+
* @param installationId - Unique installation ID (caller-defined)
|
|
2721
|
+
* @param data - {@link CreateChannelInstallationRequest} containing channel type, name, config, and fallback settings
|
|
2722
|
+
* @returns The created {@link ChannelInstallation}
|
|
2723
|
+
*/
|
|
2719
2724
|
async createInstallation(tenantId, installationId, data) {
|
|
2720
2725
|
const now = /* @__PURE__ */ new Date();
|
|
2721
2726
|
const installation = {
|
|
@@ -2733,6 +2738,14 @@ var InMemoryChannelInstallationStore = class {
|
|
|
2733
2738
|
this.installations.set(installationId, installation);
|
|
2734
2739
|
return installation;
|
|
2735
2740
|
}
|
|
2741
|
+
/**
|
|
2742
|
+
* Updates an existing channel installation. Config fields are shallow-merged.
|
|
2743
|
+
*
|
|
2744
|
+
* @param tenantId - Tenant identifier (used for isolation check)
|
|
2745
|
+
* @param installationId - Installation ID to update
|
|
2746
|
+
* @param updates - {@link UpdateChannelInstallationRequest} with fields to patch
|
|
2747
|
+
* @returns The updated {@link ChannelInstallation} or `null` if not found or tenant mismatch
|
|
2748
|
+
*/
|
|
2736
2749
|
async updateInstallation(tenantId, installationId, updates) {
|
|
2737
2750
|
const existing = this.installations.get(installationId);
|
|
2738
2751
|
if (!existing || existing.tenantId !== tenantId) return null;
|
|
@@ -2748,11 +2761,21 @@ var InMemoryChannelInstallationStore = class {
|
|
|
2748
2761
|
this.installations.set(installationId, updated);
|
|
2749
2762
|
return updated;
|
|
2750
2763
|
}
|
|
2764
|
+
/**
|
|
2765
|
+
* Deletes a channel installation.
|
|
2766
|
+
*
|
|
2767
|
+
* @param tenantId - Tenant identifier (used for isolation check)
|
|
2768
|
+
* @param installationId - Installation ID to delete
|
|
2769
|
+
* @returns `true` if deleted, `false` if not found or tenant mismatch
|
|
2770
|
+
*/
|
|
2751
2771
|
async deleteInstallation(tenantId, installationId) {
|
|
2752
2772
|
const existing = this.installations.get(installationId);
|
|
2753
2773
|
if (!existing || existing.tenantId !== tenantId) return false;
|
|
2754
2774
|
return this.installations.delete(installationId);
|
|
2755
2775
|
}
|
|
2776
|
+
/**
|
|
2777
|
+
* Clears all in-memory installations. Primarily used in tests.
|
|
2778
|
+
*/
|
|
2756
2779
|
clear() {
|
|
2757
2780
|
this.installations.clear();
|
|
2758
2781
|
}
|
|
@@ -2764,6 +2787,16 @@ var InMemoryBindingStore = class {
|
|
|
2764
2787
|
constructor() {
|
|
2765
2788
|
this.bindings = /* @__PURE__ */ new Map();
|
|
2766
2789
|
}
|
|
2790
|
+
/**
|
|
2791
|
+
* Resolves a binding for the given sender across a specific channel installation.
|
|
2792
|
+
*
|
|
2793
|
+
* Called by `MessageRouter.dispatch()` during inbound message processing.
|
|
2794
|
+
* Matches on `channel + senderId + channelInstallationId + tenantId` and
|
|
2795
|
+
* requires `enabled === true`.
|
|
2796
|
+
*
|
|
2797
|
+
* @param params - Resolution parameters
|
|
2798
|
+
* @returns The matching {@link Binding} or `null` if none found.
|
|
2799
|
+
*/
|
|
2767
2800
|
async resolve(params) {
|
|
2768
2801
|
for (const binding of this.bindings.values()) {
|
|
2769
2802
|
if (binding.channel === params.channel && binding.senderId === params.senderId && binding.channelInstallationId === params.channelInstallationId && binding.tenantId === params.tenantId && binding.enabled) {
|
|
@@ -2772,6 +2805,12 @@ var InMemoryBindingStore = class {
|
|
|
2772
2805
|
}
|
|
2773
2806
|
return null;
|
|
2774
2807
|
}
|
|
2808
|
+
/**
|
|
2809
|
+
* Creates a new sender-to-agent binding.
|
|
2810
|
+
*
|
|
2811
|
+
* @param input - {@link CreateBindingInput} defining channel, sender, target agent, and thread mode.
|
|
2812
|
+
* @returns The newly created {@link Binding}.
|
|
2813
|
+
*/
|
|
2775
2814
|
async create(input) {
|
|
2776
2815
|
const now = /* @__PURE__ */ new Date();
|
|
2777
2816
|
const binding = {
|
|
@@ -2794,6 +2833,14 @@ var InMemoryBindingStore = class {
|
|
|
2794
2833
|
this.bindings.set(binding.id, binding);
|
|
2795
2834
|
return binding;
|
|
2796
2835
|
}
|
|
2836
|
+
/**
|
|
2837
|
+
* Updates an existing binding (e.g. changing the target agent or thread mode).
|
|
2838
|
+
*
|
|
2839
|
+
* @param id - Binding ID
|
|
2840
|
+
* @param patch - Partial {@link Binding} fields to update
|
|
2841
|
+
* @returns The updated {@link Binding}
|
|
2842
|
+
* @throws {Error} If the binding does not exist
|
|
2843
|
+
*/
|
|
2797
2844
|
async update(id, patch) {
|
|
2798
2845
|
const existing = this.bindings.get(id);
|
|
2799
2846
|
if (!existing) throw new Error(`Binding ${id} not found`);
|
|
@@ -2805,9 +2852,20 @@ var InMemoryBindingStore = class {
|
|
|
2805
2852
|
this.bindings.set(id, updated);
|
|
2806
2853
|
return updated;
|
|
2807
2854
|
}
|
|
2855
|
+
/**
|
|
2856
|
+
* Deletes a binding by ID.
|
|
2857
|
+
*
|
|
2858
|
+
* @param id - Binding ID
|
|
2859
|
+
*/
|
|
2808
2860
|
async delete(id) {
|
|
2809
2861
|
this.bindings.delete(id);
|
|
2810
2862
|
}
|
|
2863
|
+
/**
|
|
2864
|
+
* Lists bindings filtered by tenant and optional channel/agent/installation.
|
|
2865
|
+
*
|
|
2866
|
+
* @param params - Filter and pagination parameters
|
|
2867
|
+
* @returns Array of matching {@link Binding} objects
|
|
2868
|
+
*/
|
|
2811
2869
|
async list(params) {
|
|
2812
2870
|
let results = Array.from(this.bindings.values()).filter((b) => {
|
|
2813
2871
|
if (b.tenantId !== params.tenantId) return false;
|
|
@@ -2820,6 +2878,12 @@ var InMemoryBindingStore = class {
|
|
|
2820
2878
|
const limit = params.limit ?? 50;
|
|
2821
2879
|
return results.slice(offset, offset + limit);
|
|
2822
2880
|
}
|
|
2881
|
+
/**
|
|
2882
|
+
* Bulk-imports bindings.
|
|
2883
|
+
*
|
|
2884
|
+
* @param bindings - Array of {@link CreateBindingInput}
|
|
2885
|
+
* @returns Array of created {@link Binding} objects
|
|
2886
|
+
*/
|
|
2823
2887
|
async import(bindings) {
|
|
2824
2888
|
const result = [];
|
|
2825
2889
|
for (const input of bindings) {
|
|
@@ -2827,9 +2891,18 @@ var InMemoryBindingStore = class {
|
|
|
2827
2891
|
}
|
|
2828
2892
|
return result;
|
|
2829
2893
|
}
|
|
2894
|
+
/**
|
|
2895
|
+
* Exports all bindings for a tenant.
|
|
2896
|
+
*
|
|
2897
|
+
* @param params - Filter by tenantId
|
|
2898
|
+
* @returns Array of {@link Binding} objects
|
|
2899
|
+
*/
|
|
2830
2900
|
async export(params) {
|
|
2831
2901
|
return this.list({ tenantId: params.tenantId, limit: 1e4 });
|
|
2832
2902
|
}
|
|
2903
|
+
/**
|
|
2904
|
+
* Clears all in-memory bindings. Primarily used in tests.
|
|
2905
|
+
*/
|
|
2833
2906
|
clear() {
|
|
2834
2907
|
this.bindings.clear();
|
|
2835
2908
|
}
|
|
@@ -3452,7 +3525,6 @@ var SqlDatabaseManager = class _SqlDatabaseManager {
|
|
|
3452
3525
|
constructor() {
|
|
3453
3526
|
this.databases = /* @__PURE__ */ new Map();
|
|
3454
3527
|
this.defaultDatabaseKeys = /* @__PURE__ */ new Map();
|
|
3455
|
-
this.configStore = null;
|
|
3456
3528
|
}
|
|
3457
3529
|
/**
|
|
3458
3530
|
* Get the singleton instance
|
|
@@ -3512,16 +3584,9 @@ var SqlDatabaseManager = class _SqlDatabaseManager {
|
|
|
3512
3584
|
}
|
|
3513
3585
|
this.defaultDatabaseKeys.set(tenantId, key);
|
|
3514
3586
|
}
|
|
3515
|
-
/**
|
|
3516
|
-
* Set the configuration store for on-demand database loading
|
|
3517
|
-
* @param store - The database configuration store
|
|
3518
|
-
*/
|
|
3519
|
-
setConfigStore(store) {
|
|
3520
|
-
this.configStore = store;
|
|
3521
|
-
}
|
|
3522
3587
|
/**
|
|
3523
3588
|
* Get a database by key for a specific tenant
|
|
3524
|
-
* If database is not registered
|
|
3589
|
+
* If database is not registered, tries to load from the store lattice
|
|
3525
3590
|
* @param tenantId - Tenant identifier (required)
|
|
3526
3591
|
* @param key - Database key (optional, uses default if not provided)
|
|
3527
3592
|
* @returns ISqlDatabase instance
|
|
@@ -3539,8 +3604,10 @@ var SqlDatabaseManager = class _SqlDatabaseManager {
|
|
|
3539
3604
|
return database;
|
|
3540
3605
|
}
|
|
3541
3606
|
}
|
|
3542
|
-
|
|
3543
|
-
const
|
|
3607
|
+
try {
|
|
3608
|
+
const { store } = getStoreLattice("default", "database");
|
|
3609
|
+
const configStore = store;
|
|
3610
|
+
const configEntry = await configStore.getConfigByKey(tenantId, dbKey);
|
|
3544
3611
|
if (configEntry) {
|
|
3545
3612
|
this.registerDatabase(tenantId, dbKey, configEntry.config);
|
|
3546
3613
|
if (!this.defaultDatabaseKeys.has(tenantId)) {
|
|
@@ -3554,6 +3621,7 @@ var SqlDatabaseManager = class _SqlDatabaseManager {
|
|
|
3554
3621
|
}
|
|
3555
3622
|
}
|
|
3556
3623
|
}
|
|
3624
|
+
} catch {
|
|
3557
3625
|
}
|
|
3558
3626
|
if (!tenantDbs) {
|
|
3559
3627
|
throw new Error(`No databases registered for tenant '${tenantId}'`);
|
|
@@ -4663,6 +4731,7 @@ var MetricsServerManager = class _MetricsServerManager {
|
|
|
4663
4731
|
this.clients = /* @__PURE__ */ new Map();
|
|
4664
4732
|
this.configs = /* @__PURE__ */ new Map();
|
|
4665
4733
|
this.defaultServerKeys = /* @__PURE__ */ new Map();
|
|
4734
|
+
this._loadingPromise = null;
|
|
4666
4735
|
}
|
|
4667
4736
|
/**
|
|
4668
4737
|
* Get the singleton instance
|
|
@@ -4673,6 +4742,32 @@ var MetricsServerManager = class _MetricsServerManager {
|
|
|
4673
4742
|
}
|
|
4674
4743
|
return _MetricsServerManager.instance;
|
|
4675
4744
|
}
|
|
4745
|
+
/**
|
|
4746
|
+
* Ensure configurations are loaded from the store lattice.
|
|
4747
|
+
* Uses a promise-lock to prevent concurrent loads.
|
|
4748
|
+
*/
|
|
4749
|
+
async _ensureLoaded() {
|
|
4750
|
+
if (this.clients.size > 0) {
|
|
4751
|
+
return;
|
|
4752
|
+
}
|
|
4753
|
+
if (this._loadingPromise) {
|
|
4754
|
+
return this._loadingPromise;
|
|
4755
|
+
}
|
|
4756
|
+
this._loadingPromise = (async () => {
|
|
4757
|
+
try {
|
|
4758
|
+
const { store } = getStoreLattice("default", "metrics");
|
|
4759
|
+
const configStore = store;
|
|
4760
|
+
const configs = await configStore.getAllConfigsWithoutTenant();
|
|
4761
|
+
for (const entry of configs) {
|
|
4762
|
+
const tenantId = entry.tenantId || "default";
|
|
4763
|
+
this.registerServer(tenantId, entry.key, entry.config);
|
|
4764
|
+
}
|
|
4765
|
+
} finally {
|
|
4766
|
+
this._loadingPromise = null;
|
|
4767
|
+
}
|
|
4768
|
+
})();
|
|
4769
|
+
return this._loadingPromise;
|
|
4770
|
+
}
|
|
4676
4771
|
/**
|
|
4677
4772
|
* Get or create tenant clients map
|
|
4678
4773
|
*/
|
|
@@ -4741,7 +4836,8 @@ var MetricsServerManager = class _MetricsServerManager {
|
|
|
4741
4836
|
* @param tenantId - Tenant identifier
|
|
4742
4837
|
* @param key - Server key (optional, uses default if not provided)
|
|
4743
4838
|
*/
|
|
4744
|
-
getClient(tenantId, key) {
|
|
4839
|
+
async getClient(tenantId, key) {
|
|
4840
|
+
await this._ensureLoaded();
|
|
4745
4841
|
const tenantClients = this.clients.get(tenantId);
|
|
4746
4842
|
if (!tenantClients) {
|
|
4747
4843
|
throw new Error(`No metrics servers registered for tenant '${tenantId}'`);
|
|
@@ -4761,7 +4857,8 @@ var MetricsServerManager = class _MetricsServerManager {
|
|
|
4761
4857
|
* @param tenantId - Tenant identifier
|
|
4762
4858
|
* @param key - Server key (optional, uses default if not provided)
|
|
4763
4859
|
*/
|
|
4764
|
-
getConfig(tenantId, key) {
|
|
4860
|
+
async getConfig(tenantId, key) {
|
|
4861
|
+
await this._ensureLoaded();
|
|
4765
4862
|
const tenantConfigs = this.configs.get(tenantId);
|
|
4766
4863
|
if (!tenantConfigs) {
|
|
4767
4864
|
throw new Error(`No metrics servers registered for tenant '${tenantId}'`);
|
|
@@ -4789,7 +4886,8 @@ var MetricsServerManager = class _MetricsServerManager {
|
|
|
4789
4886
|
* Get all registered metrics server keys with their types for a tenant
|
|
4790
4887
|
* @param tenantId - Tenant identifier
|
|
4791
4888
|
*/
|
|
4792
|
-
getServerKeys(tenantId) {
|
|
4889
|
+
async getServerKeys(tenantId) {
|
|
4890
|
+
await this._ensureLoaded();
|
|
4793
4891
|
const tenantConfigs = this.configs.get(tenantId);
|
|
4794
4892
|
if (!tenantConfigs) {
|
|
4795
4893
|
return [];
|
|
@@ -4856,20 +4954,6 @@ var MetricsServerManager = class _MetricsServerManager {
|
|
|
4856
4954
|
this.registerServer(tenantId, entry.key, entry.config);
|
|
4857
4955
|
}
|
|
4858
4956
|
}
|
|
4859
|
-
/**
|
|
4860
|
-
* Load all metrics server configurations from a store
|
|
4861
|
-
* across all tenants and register them with this manager
|
|
4862
|
-
*
|
|
4863
|
-
* @param store - The metrics server configuration store
|
|
4864
|
-
* @deprecated Use loadConfigsFromStore with specific tenant instead
|
|
4865
|
-
*/
|
|
4866
|
-
async loadAllConfigsFromStore(store) {
|
|
4867
|
-
const configs = await store.getAllConfigsWithoutTenant();
|
|
4868
|
-
for (const entry of configs) {
|
|
4869
|
-
const tenantId = entry.tenantId || "default";
|
|
4870
|
-
this.registerServer(tenantId, entry.key, entry.config);
|
|
4871
|
-
}
|
|
4872
|
-
}
|
|
4873
4957
|
};
|
|
4874
4958
|
var metricsServerManager = MetricsServerManager.getInstance();
|
|
4875
4959
|
|
|
@@ -4888,7 +4972,7 @@ ${serverKeys.map(
|
|
|
4888
4972
|
async (_input, _exeConfig) => {
|
|
4889
4973
|
try {
|
|
4890
4974
|
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId2);
|
|
4891
|
-
const servers = metricsServerManager.getServerKeys(tenantId);
|
|
4975
|
+
const servers = await metricsServerManager.getServerKeys(tenantId);
|
|
4892
4976
|
if (servers.length === 0) {
|
|
4893
4977
|
return "No metrics servers registered.";
|
|
4894
4978
|
}
|
|
@@ -4927,7 +5011,7 @@ ${serverKeys.map(
|
|
|
4927
5011
|
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId2);
|
|
4928
5012
|
let effectiveServerKeys = serverKeys;
|
|
4929
5013
|
if (connectAll) {
|
|
4930
|
-
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
5014
|
+
effectiveServerKeys = (await metricsServerManager.getServerKeys(tenantId)).map((s) => s.key);
|
|
4931
5015
|
}
|
|
4932
5016
|
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
4933
5017
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
@@ -4950,12 +5034,12 @@ To view all available data sources, please clear the current selection or reopen
|
|
|
4950
5034
|
const allDataSources = [];
|
|
4951
5035
|
for (const serverKey of filteredServerKeys) {
|
|
4952
5036
|
try {
|
|
4953
|
-
const config = metricsServerManager.getConfig(tenantId, serverKey);
|
|
5037
|
+
const config = await metricsServerManager.getConfig(tenantId, serverKey);
|
|
4954
5038
|
if (config.type !== "semantic") {
|
|
4955
5039
|
console.warn(`Server "${serverKey}" is not a semantic metrics server, skipping.`);
|
|
4956
5040
|
continue;
|
|
4957
5041
|
}
|
|
4958
|
-
const client = metricsServerManager.getClient(tenantId, serverKey);
|
|
5042
|
+
const client = await metricsServerManager.getClient(tenantId, serverKey);
|
|
4959
5043
|
const dataSources = await client.getDataSources();
|
|
4960
5044
|
const selectedIds = config.selectedDataSources || [];
|
|
4961
5045
|
const filteredDataSources = selectedIds.length > 0 ? dataSources.filter((ds) => selectedIds.includes(String(ds.id))) : dataSources;
|
|
@@ -5046,7 +5130,7 @@ ${serverKeys.map(
|
|
|
5046
5130
|
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId2);
|
|
5047
5131
|
let effectiveServerKeys = serverKeys;
|
|
5048
5132
|
if (connectAll) {
|
|
5049
|
-
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
5133
|
+
effectiveServerKeys = (await metricsServerManager.getServerKeys(tenantId)).map((s) => s.key);
|
|
5050
5134
|
}
|
|
5051
5135
|
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
5052
5136
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
@@ -5058,11 +5142,11 @@ ${serverKeys.map(
|
|
|
5058
5142
|
if (!filteredServerKeys.includes(serverKey)) {
|
|
5059
5143
|
return `Error: serverKey "${serverKey}" is not available for tenant "${tenantId}". Available servers: [${filteredServerKeys.join(", ")}]`;
|
|
5060
5144
|
}
|
|
5061
|
-
const config = metricsServerManager.getConfig(tenantId, serverKey);
|
|
5145
|
+
const config = await metricsServerManager.getConfig(tenantId, serverKey);
|
|
5062
5146
|
if (config.type !== "semantic") {
|
|
5063
5147
|
return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
|
|
5064
5148
|
}
|
|
5065
|
-
const client = metricsServerManager.getClient(tenantId, serverKey);
|
|
5149
|
+
const client = await metricsServerManager.getClient(tenantId, serverKey);
|
|
5066
5150
|
const targetDatasourceIds = datasourceIds && datasourceIds.length > 0 ? datasourceIds : metricsDataSource?.datasourceId ? [metricsDataSource.datasourceId] : client.getSelectedDataSources();
|
|
5067
5151
|
if (targetDatasourceIds.length === 0) {
|
|
5068
5152
|
return `Error: No data sources specified and no default data sources configured for server "${serverKey}".`;
|
|
@@ -5204,7 +5288,7 @@ ${serverKeys.map(
|
|
|
5204
5288
|
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId2);
|
|
5205
5289
|
let effectiveServerKeys = serverKeys;
|
|
5206
5290
|
if (connectAll) {
|
|
5207
|
-
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
5291
|
+
effectiveServerKeys = (await metricsServerManager.getServerKeys(tenantId)).map((s) => s.key);
|
|
5208
5292
|
}
|
|
5209
5293
|
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
5210
5294
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
@@ -5220,11 +5304,11 @@ ${serverKeys.map(
|
|
|
5220
5304
|
if (!metricName) {
|
|
5221
5305
|
return "Error: metricName parameter is required.";
|
|
5222
5306
|
}
|
|
5223
|
-
const config = metricsServerManager.getConfig(tenantId, serverKey);
|
|
5307
|
+
const config = await metricsServerManager.getConfig(tenantId, serverKey);
|
|
5224
5308
|
if (config.type !== "semantic") {
|
|
5225
5309
|
return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
|
|
5226
5310
|
}
|
|
5227
|
-
const client = metricsServerManager.getClient(tenantId, serverKey);
|
|
5311
|
+
const client = await metricsServerManager.getClient(tenantId, serverKey);
|
|
5228
5312
|
const targetDatasourceIds = datasourceId ? [datasourceId] : client.getSelectedDataSources();
|
|
5229
5313
|
if (targetDatasourceIds.length === 0) {
|
|
5230
5314
|
return `Error: No datasourceId specified and no default data sources configured for server "${serverKey}".`;
|
|
@@ -5440,7 +5524,7 @@ ${serverKeys.map(
|
|
|
5440
5524
|
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId2);
|
|
5441
5525
|
let effectiveServerKeys = serverKeys;
|
|
5442
5526
|
if (connectAll) {
|
|
5443
|
-
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
5527
|
+
effectiveServerKeys = (await metricsServerManager.getServerKeys(tenantId)).map((s) => s.key);
|
|
5444
5528
|
}
|
|
5445
5529
|
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
5446
5530
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
@@ -5459,11 +5543,11 @@ ${serverKeys.map(
|
|
|
5459
5543
|
if (!metrics || metrics.length === 0) {
|
|
5460
5544
|
return "Error: metrics parameter is required (at least one metric name).";
|
|
5461
5545
|
}
|
|
5462
|
-
const config = metricsServerManager.getConfig(tenantId, serverKey);
|
|
5546
|
+
const config = await metricsServerManager.getConfig(tenantId, serverKey);
|
|
5463
5547
|
if (config.type !== "semantic") {
|
|
5464
5548
|
return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
|
|
5465
5549
|
}
|
|
5466
|
-
const client = metricsServerManager.getClient(tenantId, serverKey);
|
|
5550
|
+
const client = await metricsServerManager.getClient(tenantId, serverKey);
|
|
5467
5551
|
const semanticFilters = (filters || []).map((f) => ({
|
|
5468
5552
|
dimension: f.dimension,
|
|
5469
5553
|
operator: f.operator,
|
|
@@ -5521,7 +5605,7 @@ ${serverKeys.map(
|
|
|
5521
5605
|
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId2);
|
|
5522
5606
|
let effectiveServerKeys = serverKeys;
|
|
5523
5607
|
if (connectAll) {
|
|
5524
|
-
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
5608
|
+
effectiveServerKeys = (await metricsServerManager.getServerKeys(tenantId)).map((s) => s.key);
|
|
5525
5609
|
}
|
|
5526
5610
|
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
5527
5611
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
@@ -5533,11 +5617,11 @@ ${serverKeys.map(
|
|
|
5533
5617
|
if (!filteredServerKeys.includes(serverKey)) {
|
|
5534
5618
|
return `Error: serverKey "${serverKey}" is not available for tenant "${tenantId}". Available servers: [${filteredServerKeys.join(", ")}]`;
|
|
5535
5619
|
}
|
|
5536
|
-
const config = metricsServerManager.getConfig(tenantId, serverKey);
|
|
5620
|
+
const config = await metricsServerManager.getConfig(tenantId, serverKey);
|
|
5537
5621
|
if (config.type !== "semantic") {
|
|
5538
5622
|
return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
|
|
5539
5623
|
}
|
|
5540
|
-
const client = metricsServerManager.getClient(tenantId, serverKey);
|
|
5624
|
+
const client = await metricsServerManager.getClient(tenantId, serverKey);
|
|
5541
5625
|
const targetDatasourceIds = datasourceIds && datasourceIds.length > 0 ? datasourceIds : metricsDataSource?.datasourceId ? [metricsDataSource.datasourceId] : client.getSelectedDataSources();
|
|
5542
5626
|
if (targetDatasourceIds.length === 0) {
|
|
5543
5627
|
return `Error: No data sources specified and no default data sources configured for server "${serverKey}".`;
|
|
@@ -5626,7 +5710,7 @@ ${serverKeys.map(
|
|
|
5626
5710
|
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId2);
|
|
5627
5711
|
let effectiveServerKeys = serverKeys;
|
|
5628
5712
|
if (connectAll) {
|
|
5629
|
-
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
5713
|
+
effectiveServerKeys = (await metricsServerManager.getServerKeys(tenantId)).map((s) => s.key);
|
|
5630
5714
|
}
|
|
5631
5715
|
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
5632
5716
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
@@ -5642,11 +5726,11 @@ ${serverKeys.map(
|
|
|
5642
5726
|
if (!tableName) {
|
|
5643
5727
|
return "Error: tableName parameter is required.";
|
|
5644
5728
|
}
|
|
5645
|
-
const config = metricsServerManager.getConfig(tenantId, serverKey);
|
|
5729
|
+
const config = await metricsServerManager.getConfig(tenantId, serverKey);
|
|
5646
5730
|
if (config.type !== "semantic") {
|
|
5647
5731
|
return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
|
|
5648
5732
|
}
|
|
5649
|
-
const client = metricsServerManager.getClient(tenantId, serverKey);
|
|
5733
|
+
const client = await metricsServerManager.getClient(tenantId, serverKey);
|
|
5650
5734
|
const targetDatasourceIds = datasourceId ? [datasourceId] : client.getSelectedDataSources();
|
|
5651
5735
|
if (targetDatasourceIds.length === 0) {
|
|
5652
5736
|
return `Error: No datasourceId specified and no default data sources configured for server "${serverKey}".`;
|
|
@@ -5766,7 +5850,7 @@ ${serverKeys.map(
|
|
|
5766
5850
|
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId2);
|
|
5767
5851
|
let effectiveServerKeys = serverKeys;
|
|
5768
5852
|
if (connectAll) {
|
|
5769
|
-
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
5853
|
+
effectiveServerKeys = (await metricsServerManager.getServerKeys(tenantId)).map((s) => s.key);
|
|
5770
5854
|
}
|
|
5771
5855
|
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
5772
5856
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
@@ -5785,11 +5869,11 @@ ${serverKeys.map(
|
|
|
5785
5869
|
if (!customSql || customSql.trim().length === 0) {
|
|
5786
5870
|
return "Error: customSql parameter is required and cannot be empty.";
|
|
5787
5871
|
}
|
|
5788
|
-
const config = metricsServerManager.getConfig(tenantId, serverKey);
|
|
5872
|
+
const config = await metricsServerManager.getConfig(tenantId, serverKey);
|
|
5789
5873
|
if (config.type !== "semantic") {
|
|
5790
5874
|
return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
|
|
5791
5875
|
}
|
|
5792
|
-
const client = metricsServerManager.getClient(tenantId, serverKey);
|
|
5876
|
+
const client = await metricsServerManager.getClient(tenantId, serverKey);
|
|
5793
5877
|
const result = await client.executeSqlQuery({
|
|
5794
5878
|
datasourceId,
|
|
5795
5879
|
customSql,
|
|
@@ -12119,6 +12203,14 @@ var ThreadStatus2 = /* @__PURE__ */ ((ThreadStatus3) => {
|
|
|
12119
12203
|
return ThreadStatus3;
|
|
12120
12204
|
})(ThreadStatus2 || {});
|
|
12121
12205
|
var Agent = class {
|
|
12206
|
+
/**
|
|
12207
|
+
* Constructs an Agent instance.
|
|
12208
|
+
*
|
|
12209
|
+
* Prefer {@link AgentInstanceManager.getAgent} over direct construction — it
|
|
12210
|
+
* ensures a single instance per thread.
|
|
12211
|
+
*
|
|
12212
|
+
* @param params - {@link AgentThreadInterface}
|
|
12213
|
+
*/
|
|
12122
12214
|
constructor({
|
|
12123
12215
|
assistant_id,
|
|
12124
12216
|
thread_id,
|
|
@@ -12328,9 +12420,10 @@ var Agent = class {
|
|
|
12328
12420
|
command: p.command,
|
|
12329
12421
|
custom_run_config: p.custom_run_config ?? queueMessageData.custom_run_config
|
|
12330
12422
|
}, signal);
|
|
12331
|
-
await this.queueStore?.
|
|
12423
|
+
await this.queueStore?.removeMessage(p.id);
|
|
12332
12424
|
const runStatus = await this.getRunStatus();
|
|
12333
12425
|
const state = await this.getCurrentState();
|
|
12426
|
+
const customRunConfig = p.custom_run_config ?? queueMessageData.custom_run_config;
|
|
12334
12427
|
if (runStatus === "interrupted" /* INTERRUPTED */) {
|
|
12335
12428
|
this.publish("message:interrupted", {
|
|
12336
12429
|
type: "message:interrupted",
|
|
@@ -12355,6 +12448,12 @@ var Agent = class {
|
|
|
12355
12448
|
state
|
|
12356
12449
|
});
|
|
12357
12450
|
}
|
|
12451
|
+
this.publish("reply:ready", {
|
|
12452
|
+
type: "reply:ready",
|
|
12453
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
12454
|
+
state,
|
|
12455
|
+
customRunConfig
|
|
12456
|
+
});
|
|
12358
12457
|
} catch (error) {
|
|
12359
12458
|
console.error(`STEER/Command message ${p.id} execution failed:`, error);
|
|
12360
12459
|
this.addChunk({
|
|
@@ -12370,7 +12469,8 @@ var Agent = class {
|
|
|
12370
12469
|
error: error instanceof Error ? error.message : String(error),
|
|
12371
12470
|
timestamp: /* @__PURE__ */ new Date()
|
|
12372
12471
|
});
|
|
12373
|
-
|
|
12472
|
+
await this.queueStore?.removeMessage(p.id);
|
|
12473
|
+
continue;
|
|
12374
12474
|
}
|
|
12375
12475
|
}
|
|
12376
12476
|
}
|
|
@@ -12406,7 +12506,7 @@ var Agent = class {
|
|
|
12406
12506
|
const runStatus = await this.getRunStatus();
|
|
12407
12507
|
const state = await this.getCurrentState();
|
|
12408
12508
|
for (const p of remainingPendings) {
|
|
12409
|
-
await this.queueStore?.
|
|
12509
|
+
await this.queueStore?.removeMessage(p.id);
|
|
12410
12510
|
if (runStatus === "interrupted" /* INTERRUPTED */) {
|
|
12411
12511
|
this.publish("message:interrupted", {
|
|
12412
12512
|
type: "message:interrupted",
|
|
@@ -12432,6 +12532,12 @@ var Agent = class {
|
|
|
12432
12532
|
});
|
|
12433
12533
|
}
|
|
12434
12534
|
}
|
|
12535
|
+
this.publish("reply:ready", {
|
|
12536
|
+
type: "reply:ready",
|
|
12537
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
12538
|
+
state,
|
|
12539
|
+
customRunConfig: remainingPendings[0]?.custom_run_config ?? firstQueueMessage?.custom_run_config
|
|
12540
|
+
});
|
|
12435
12541
|
} catch (error) {
|
|
12436
12542
|
console.error(`COLLECT mode execution failed:`, error);
|
|
12437
12543
|
for (const p of remainingPendings) {
|
|
@@ -12448,8 +12554,8 @@ var Agent = class {
|
|
|
12448
12554
|
error: error instanceof Error ? error.message : String(error),
|
|
12449
12555
|
timestamp: /* @__PURE__ */ new Date()
|
|
12450
12556
|
});
|
|
12557
|
+
await this.queueStore?.removeMessage(p.id);
|
|
12451
12558
|
}
|
|
12452
|
-
throw error;
|
|
12453
12559
|
}
|
|
12454
12560
|
} else if (this.queueMode.mode === "followup" /* FOLLOWUP */) {
|
|
12455
12561
|
for (const p of remainingPendings) {
|
|
@@ -12477,9 +12583,10 @@ var Agent = class {
|
|
|
12477
12583
|
input,
|
|
12478
12584
|
custom_run_config: p.custom_run_config ?? queueMessageData.custom_run_config
|
|
12479
12585
|
}, signal);
|
|
12480
|
-
await this.queueStore?.
|
|
12586
|
+
await this.queueStore?.removeMessage(p.id);
|
|
12481
12587
|
const runStatus = await this.getRunStatus();
|
|
12482
12588
|
const state = await this.getCurrentState();
|
|
12589
|
+
const customRunConfig = p.custom_run_config ?? queueMessageData.custom_run_config;
|
|
12483
12590
|
if (runStatus === "interrupted" /* INTERRUPTED */) {
|
|
12484
12591
|
this.publish("message:interrupted", {
|
|
12485
12592
|
type: "message:interrupted",
|
|
@@ -12504,6 +12611,12 @@ var Agent = class {
|
|
|
12504
12611
|
state
|
|
12505
12612
|
});
|
|
12506
12613
|
}
|
|
12614
|
+
this.publish("reply:ready", {
|
|
12615
|
+
type: "reply:ready",
|
|
12616
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
12617
|
+
state,
|
|
12618
|
+
customRunConfig
|
|
12619
|
+
});
|
|
12507
12620
|
} catch (error) {
|
|
12508
12621
|
console.error(`FOLLOWUP mode message ${p.id} execution failed:`, error);
|
|
12509
12622
|
this.addChunk({
|
|
@@ -12519,7 +12632,8 @@ var Agent = class {
|
|
|
12519
12632
|
error: error instanceof Error ? error.message : String(error),
|
|
12520
12633
|
timestamp: /* @__PURE__ */ new Date()
|
|
12521
12634
|
});
|
|
12522
|
-
|
|
12635
|
+
await this.queueStore?.removeMessage(p.id);
|
|
12636
|
+
continue;
|
|
12523
12637
|
}
|
|
12524
12638
|
}
|
|
12525
12639
|
}
|
|
@@ -12545,9 +12659,25 @@ var Agent = class {
|
|
|
12545
12659
|
setQueueStore(store) {
|
|
12546
12660
|
this.queueStore = store;
|
|
12547
12661
|
}
|
|
12662
|
+
/**
|
|
12663
|
+
* Push a chunk into the streaming buffer for this thread.
|
|
12664
|
+
*
|
|
12665
|
+
* Consumers read chunks via {@link chunkStream}.
|
|
12666
|
+
*
|
|
12667
|
+
* @param content - The message chunk to buffer
|
|
12668
|
+
*/
|
|
12548
12669
|
addChunk(content) {
|
|
12549
12670
|
return this.chunkBuffer.addChunk(this.thread_id, content);
|
|
12550
12671
|
}
|
|
12672
|
+
/**
|
|
12673
|
+
* Returns an async iterator over new chunks since the given message ID.
|
|
12674
|
+
*
|
|
12675
|
+
* Used by SSE endpoints to stream agent output to clients in real time.
|
|
12676
|
+
*
|
|
12677
|
+
* @param message_id - The client message ID to start streaming from
|
|
12678
|
+
* @param stopTypes - Optional chunk types that terminate the stream
|
|
12679
|
+
* @returns An async iterable yielding {@link MessageChunk} objects
|
|
12680
|
+
*/
|
|
12551
12681
|
chunkStream(message_id, stopTypes) {
|
|
12552
12682
|
const stream = this.chunkBuffer.getNewChunksSinceContentIterator(
|
|
12553
12683
|
this.thread_id,
|
|
@@ -12636,13 +12766,21 @@ var Agent = class {
|
|
|
12636
12766
|
};
|
|
12637
12767
|
}
|
|
12638
12768
|
/**
|
|
12639
|
-
*
|
|
12769
|
+
* Override the thread's queue processing mode.
|
|
12770
|
+
*
|
|
12771
|
+
* @param config - Partial {@link ThreadQueueConfig} (e.g. `{ mode: QueueMode.FOLLOWUP }`)
|
|
12640
12772
|
*/
|
|
12641
12773
|
async setQueueConfig(config) {
|
|
12642
12774
|
this.queueMode = { ...this.queueMode, ...config };
|
|
12643
12775
|
}
|
|
12644
12776
|
/**
|
|
12645
|
-
*
|
|
12777
|
+
* Abort any ongoing queue processing without clearing the queue.
|
|
12778
|
+
*
|
|
12779
|
+
* Used internally by STEER mode to interrupt the current execution so the
|
|
12780
|
+
* steer message can be processed next. For a full abort that also clears
|
|
12781
|
+
* pending messages, use {@link abort}.
|
|
12782
|
+
*
|
|
12783
|
+
* @see {@link abort}
|
|
12646
12784
|
*/
|
|
12647
12785
|
stopQueueProcessor() {
|
|
12648
12786
|
if (this.abortController) {
|
|
@@ -12651,14 +12789,34 @@ var Agent = class {
|
|
|
12651
12789
|
}
|
|
12652
12790
|
}
|
|
12653
12791
|
/**
|
|
12654
|
-
*
|
|
12655
|
-
*
|
|
12656
|
-
*
|
|
12657
|
-
*
|
|
12658
|
-
*
|
|
12659
|
-
*
|
|
12660
|
-
* -
|
|
12661
|
-
* -
|
|
12792
|
+
* Enqueue a message for this thread.
|
|
12793
|
+
*
|
|
12794
|
+
* Messages are always queued; the queue processor starts automatically if idle.
|
|
12795
|
+
* Returns immediately with the message ID — execution is asynchronous.
|
|
12796
|
+
*
|
|
12797
|
+
* **Queue modes** (via the optional `mode` param):
|
|
12798
|
+
* - `COLLECT` (default) — Batch multiple pending messages into one agent call.
|
|
12799
|
+
* - `FOLLOWUP` — Process messages one at a time in order.
|
|
12800
|
+
* - `STEER` — High-priority, inserted at queue head, interrupts current processing.
|
|
12801
|
+
*
|
|
12802
|
+
* **Format**: Supports both `input.message` (legacy string) and `input.messages[]`
|
|
12803
|
+
* (array of `{ role, content }` objects). The array form takes precedence.
|
|
12804
|
+
*
|
|
12805
|
+
* The `custom_run_config` field is round-tripped through the queue and emitted
|
|
12806
|
+
* back in {@link ReplyReadyEvent}, enabling callers to attach routing metadata
|
|
12807
|
+
* (e.g. `_replyTarget` for channel reply).
|
|
12808
|
+
*
|
|
12809
|
+
* @param queueMessage - The message to enqueue
|
|
12810
|
+
* @param mode - Optional queue mode override (defaults to thread's current mode)
|
|
12811
|
+
* @returns `{ queued: true, executed: false, messageId }` — execution happens asynchronously
|
|
12812
|
+
*
|
|
12813
|
+
* @example
|
|
12814
|
+
* ```ts
|
|
12815
|
+
* await agent.addMessage({
|
|
12816
|
+
* input: { message: "Hello" },
|
|
12817
|
+
* custom_run_config: { _replyTarget: { adapterChannel: "lark", rawTarget: { chatId: "xxx" } } },
|
|
12818
|
+
* });
|
|
12819
|
+
* ```
|
|
12662
12820
|
*/
|
|
12663
12821
|
async addMessage(queueMessage, mode) {
|
|
12664
12822
|
const useMode = mode ?? this.queueMode.mode;
|
|
@@ -12752,8 +12910,13 @@ var Agent = class {
|
|
|
12752
12910
|
return { queued: true, executed: false, messageId };
|
|
12753
12911
|
}
|
|
12754
12912
|
/**
|
|
12755
|
-
* Start queue processor if not already running
|
|
12756
|
-
*
|
|
12913
|
+
* Start the queue processor if it is not already running.
|
|
12914
|
+
*
|
|
12915
|
+
* Called automatically by {@link addMessage} and {@link resumeTask}.
|
|
12916
|
+
* Safe to call externally — it is a no-op if processing is already active.
|
|
12917
|
+
*
|
|
12918
|
+
* Emits `thread:busy` before starting, and starts the {@link waitingForQueueEnd}
|
|
12919
|
+
* loop with a fresh {@link AbortController}.
|
|
12757
12920
|
*/
|
|
12758
12921
|
async startQueueProcessorIfNeeded() {
|
|
12759
12922
|
const store = this.getQueueStore();
|
|
@@ -12801,6 +12964,12 @@ var Agent = class {
|
|
|
12801
12964
|
type: "system"
|
|
12802
12965
|
});
|
|
12803
12966
|
}
|
|
12967
|
+
/**
|
|
12968
|
+
* Returns a LangGraph StateSnapshot for this thread.
|
|
12969
|
+
*
|
|
12970
|
+
* Includes `state.values.messages` (full conversation history) and
|
|
12971
|
+
* `state.tasks` / `state.next` (execution progress).
|
|
12972
|
+
*/
|
|
12804
12973
|
async getCurrentState() {
|
|
12805
12974
|
const { runnable_agent } = await this.getLatticeClientAndRuntimeConfig();
|
|
12806
12975
|
const state = await runnable_agent.getState({
|
|
@@ -12808,6 +12977,14 @@ var Agent = class {
|
|
|
12808
12977
|
});
|
|
12809
12978
|
return state;
|
|
12810
12979
|
}
|
|
12980
|
+
/**
|
|
12981
|
+
* Returns the conversation history as normalized message objects.
|
|
12982
|
+
*
|
|
12983
|
+
* Filters to `human`, `ai`, and `tool` message types. Each entry has
|
|
12984
|
+
* `{ id, role, content }` plus any LangChain kwargs.
|
|
12985
|
+
*
|
|
12986
|
+
* @returns Array of message objects with `id`, `role`, and `content`
|
|
12987
|
+
*/
|
|
12811
12988
|
async getCurrentMessages() {
|
|
12812
12989
|
const state = await this.getCurrentState();
|
|
12813
12990
|
const messages = state.values.messages || [];
|
|
@@ -12830,6 +13007,14 @@ var Agent = class {
|
|
|
12830
13007
|
const image = await drawableGraph.drawMermaid();
|
|
12831
13008
|
return image;
|
|
12832
13009
|
}
|
|
13010
|
+
/**
|
|
13011
|
+
* Determine the current thread execution status.
|
|
13012
|
+
*
|
|
13013
|
+
* Checks LangGraph's `state.tasks` for interrupts and `state.next` for
|
|
13014
|
+
* pending steps.
|
|
13015
|
+
*
|
|
13016
|
+
* @returns {@link ThreadStatus} — `IDLE`, `BUSY`, or `INTERRUPTED`
|
|
13017
|
+
*/
|
|
12833
13018
|
async getRunStatus() {
|
|
12834
13019
|
const state = await this.getCurrentState();
|
|
12835
13020
|
const isInterrupted = state.tasks?.some(
|
|
@@ -12844,9 +13029,14 @@ var Agent = class {
|
|
|
12844
13029
|
return "idle" /* IDLE */;
|
|
12845
13030
|
}
|
|
12846
13031
|
/**
|
|
12847
|
-
* Resume
|
|
12848
|
-
*
|
|
12849
|
-
*
|
|
13032
|
+
* Resume processing after a server restart.
|
|
13033
|
+
*
|
|
13034
|
+
* Resets any stuck "processing" messages back to "pending" and restarts the
|
|
13035
|
+
* queue processor. Skips threads that are in `INTERRUPTED` state (the
|
|
13036
|
+
* interruption was intentional).
|
|
13037
|
+
*
|
|
13038
|
+
* Called during gateway startup to recover threads that were mid-execution
|
|
13039
|
+
* when the server went down.
|
|
12850
13040
|
*/
|
|
12851
13041
|
async resumeTask() {
|
|
12852
13042
|
try {
|
|
@@ -12868,9 +13058,14 @@ var Agent = class {
|
|
|
12868
13058
|
await this.startQueueProcessorIfNeeded();
|
|
12869
13059
|
}
|
|
12870
13060
|
/**
|
|
12871
|
-
*
|
|
12872
|
-
*
|
|
12873
|
-
*
|
|
13061
|
+
* Fully abort all activity on this thread.
|
|
13062
|
+
*
|
|
13063
|
+
* Aborts any in-flight agent execution (via {@link AbortController}) and
|
|
13064
|
+
* clears all pending and processing messages from the queue. Also marks
|
|
13065
|
+
* the chunk buffer thread as aborted so streaming consumers can detect it.
|
|
13066
|
+
*
|
|
13067
|
+
* Unlike {@link stopQueueProcessor}, this is a destructive abort — the
|
|
13068
|
+
* queue is drained.
|
|
12874
13069
|
*/
|
|
12875
13070
|
async abort() {
|
|
12876
13071
|
if (this.abortController) {
|
|
@@ -12888,22 +13083,44 @@ var Agent = class {
|
|
|
12888
13083
|
return this.abortController?.signal.aborted ?? false;
|
|
12889
13084
|
}
|
|
12890
13085
|
/**
|
|
12891
|
-
* Subscribe to lifecycle
|
|
12892
|
-
*
|
|
13086
|
+
* Subscribe to a lifecycle event for this specific thread.
|
|
13087
|
+
*
|
|
13088
|
+
* Event names are namespaced as `{eventName}:{tenantId}:{threadId}` so
|
|
13089
|
+
* listeners only receive events for this agent instance.
|
|
13090
|
+
*
|
|
13091
|
+
* @param eventName - One of {@link AgentLifecycleEventName}
|
|
13092
|
+
* @param callback - Handler receiving the event data payload
|
|
13093
|
+
*
|
|
13094
|
+
* @example
|
|
13095
|
+
* ```ts
|
|
13096
|
+
* agent.subscribe("message:completed", (evt) => {
|
|
13097
|
+
* console.log("AI response:", evt.state?.values?.messages);
|
|
13098
|
+
* });
|
|
13099
|
+
* ```
|
|
12893
13100
|
*/
|
|
12894
13101
|
subscribe(eventName, callback) {
|
|
12895
13102
|
const namespacedEvent = `${eventName}:${this.tenant_id}:${this.thread_id}`;
|
|
12896
13103
|
event_bus_default.subscribe(namespacedEvent, callback);
|
|
12897
13104
|
}
|
|
12898
13105
|
/**
|
|
12899
|
-
*
|
|
13106
|
+
* Remove a previously registered event listener.
|
|
13107
|
+
*
|
|
13108
|
+
* @param eventName - The event that was subscribed to
|
|
13109
|
+
* @param callback - The same function reference used in {@link subscribe}
|
|
12900
13110
|
*/
|
|
12901
13111
|
unsubscribe(eventName, callback) {
|
|
12902
13112
|
const namespacedEvent = `${eventName}:${this.tenant_id}:${this.thread_id}`;
|
|
12903
13113
|
event_bus_default.unsubscribe(namespacedEvent, callback);
|
|
12904
13114
|
}
|
|
12905
13115
|
/**
|
|
12906
|
-
* Subscribe to lifecycle
|
|
13116
|
+
* Subscribe to a lifecycle event once — the listener is removed after the
|
|
13117
|
+
* first invocation.
|
|
13118
|
+
*
|
|
13119
|
+
* Ideal for one-shot async patterns (e.g. waiting for `reply:ready` before
|
|
13120
|
+
* sending a channel reply).
|
|
13121
|
+
*
|
|
13122
|
+
* @param eventName - One of {@link AgentLifecycleEventName}
|
|
13123
|
+
* @param callback - Handler receiving the event data payload
|
|
12907
13124
|
*/
|
|
12908
13125
|
subscribeOnce(eventName, callback) {
|
|
12909
13126
|
const namespacedEvent = `${eventName}:${this.tenant_id}:${this.thread_id}`;
|
|
@@ -12917,6 +13134,12 @@ var Agent = class {
|
|
|
12917
13134
|
console.log(namespacedEvent);
|
|
12918
13135
|
event_bus_default.publish(namespacedEvent, data);
|
|
12919
13136
|
}
|
|
13137
|
+
/**
|
|
13138
|
+
* Track a sub-agent async task spawned by this agent.
|
|
13139
|
+
*
|
|
13140
|
+
* Tasks are monitored by the agent task consumer in `packages/gateway`
|
|
13141
|
+
* and their status can be polled via {@link getAsyncTasks}.
|
|
13142
|
+
*/
|
|
12920
13143
|
addAsyncTask(task) {
|
|
12921
13144
|
this.asyncTasks.push(task);
|
|
12922
13145
|
}
|
|
@@ -12926,6 +13149,12 @@ var Agent = class {
|
|
|
12926
13149
|
getAsyncTask(taskId) {
|
|
12927
13150
|
return this.asyncTasks.find((t) => t.taskId === taskId);
|
|
12928
13151
|
}
|
|
13152
|
+
/**
|
|
13153
|
+
* Update the status of a tracked async task.
|
|
13154
|
+
*
|
|
13155
|
+
* Terminal states (`completed`, `failed`, `cancelled`) automatically
|
|
13156
|
+
* set `completedAt` to the current timestamp.
|
|
13157
|
+
*/
|
|
12929
13158
|
updateAsyncTaskStatus(taskId, status) {
|
|
12930
13159
|
const task = this.getAsyncTask(taskId);
|
|
12931
13160
|
if (!task) return;
|
|
@@ -13291,6 +13520,65 @@ function createSchedulerMiddleware(options = {}) {
|
|
|
13291
13520
|
});
|
|
13292
13521
|
}
|
|
13293
13522
|
|
|
13523
|
+
// src/agent_lattice/builders/CustomMiddlewareRegistry.ts
|
|
13524
|
+
var CustomMiddlewareRegistry = class {
|
|
13525
|
+
/**
|
|
13526
|
+
* Register a custom middleware factory under the given key.
|
|
13527
|
+
*
|
|
13528
|
+
* The key is referenced by `config.key` in the database middleware configuration.
|
|
13529
|
+
* When an agent is built, the framework looks up this key and calls the factory
|
|
13530
|
+
* with the remaining config fields.
|
|
13531
|
+
*
|
|
13532
|
+
* @param key - Unique identifier, referenced in database config as `config.key`
|
|
13533
|
+
* @param factory - Function that receives config (minus `key`) and returns an AgentMiddleware
|
|
13534
|
+
*
|
|
13535
|
+
* @example
|
|
13536
|
+
* ```ts
|
|
13537
|
+
* CustomMiddlewareRegistry.register("my-logger", (config) =>
|
|
13538
|
+
* createMiddleware({ name: "Logger", beforeAgent: async () => { ... } }),
|
|
13539
|
+
* );
|
|
13540
|
+
* ```
|
|
13541
|
+
*/
|
|
13542
|
+
static register(key, factory) {
|
|
13543
|
+
this.factories.set(key, factory);
|
|
13544
|
+
}
|
|
13545
|
+
/**
|
|
13546
|
+
* Remove a previously registered factory.
|
|
13547
|
+
*
|
|
13548
|
+
* @param key - The factory key to unregister
|
|
13549
|
+
* @returns `true` if a factory was removed, `false` if the key was not found
|
|
13550
|
+
*/
|
|
13551
|
+
static unregister(key) {
|
|
13552
|
+
return this.factories.delete(key);
|
|
13553
|
+
}
|
|
13554
|
+
/**
|
|
13555
|
+
* Look up a factory by key.
|
|
13556
|
+
*
|
|
13557
|
+
* @param key - The factory key
|
|
13558
|
+
* @returns The factory function, or `undefined` if not registered
|
|
13559
|
+
*/
|
|
13560
|
+
static get(key) {
|
|
13561
|
+
return this.factories.get(key);
|
|
13562
|
+
}
|
|
13563
|
+
/**
|
|
13564
|
+
* Check whether a factory is registered under the given key.
|
|
13565
|
+
*
|
|
13566
|
+
* @param key - The factory key to check
|
|
13567
|
+
*/
|
|
13568
|
+
static has(key) {
|
|
13569
|
+
return this.factories.has(key);
|
|
13570
|
+
}
|
|
13571
|
+
/**
|
|
13572
|
+
* Get all currently registered factory keys.
|
|
13573
|
+
*
|
|
13574
|
+
* @returns Array of registered key strings
|
|
13575
|
+
*/
|
|
13576
|
+
static list() {
|
|
13577
|
+
return Array.from(this.factories.keys());
|
|
13578
|
+
}
|
|
13579
|
+
};
|
|
13580
|
+
CustomMiddlewareRegistry.factories = /* @__PURE__ */ new Map();
|
|
13581
|
+
|
|
13294
13582
|
// src/agent_lattice/builders/commonMiddleware.ts
|
|
13295
13583
|
async function createCommonMiddlewares(middlewareConfigs, filesystemBackend, fsIsExised) {
|
|
13296
13584
|
const middlewares = [];
|
|
@@ -13367,6 +13655,21 @@ async function createCommonMiddlewares(middlewareConfigs, filesystemBackend, fsI
|
|
|
13367
13655
|
case "scheduler":
|
|
13368
13656
|
middlewares.push(createSchedulerMiddleware(config.config));
|
|
13369
13657
|
break;
|
|
13658
|
+
case "custom":
|
|
13659
|
+
{
|
|
13660
|
+
const customConfig = config.config;
|
|
13661
|
+
const { key, ...rest } = customConfig;
|
|
13662
|
+
const factory = CustomMiddlewareRegistry.get(key);
|
|
13663
|
+
if (factory) {
|
|
13664
|
+
const middleware = factory(rest);
|
|
13665
|
+
middlewares.push(middleware instanceof Promise ? await middleware : middleware);
|
|
13666
|
+
} else {
|
|
13667
|
+
console.warn(
|
|
13668
|
+
`[custom middleware] No factory registered for key "${key}". Use CustomMiddlewareRegistry.register("${key}", factory) before building the agent.`
|
|
13669
|
+
);
|
|
13670
|
+
}
|
|
13671
|
+
}
|
|
13672
|
+
break;
|
|
13370
13673
|
}
|
|
13371
13674
|
}
|
|
13372
13675
|
return middlewares;
|
|
@@ -18110,6 +18413,75 @@ function mergeAgentConfig(parent, child) {
|
|
|
18110
18413
|
return merged;
|
|
18111
18414
|
}
|
|
18112
18415
|
|
|
18416
|
+
// src/store_lattice/configureStores.ts
|
|
18417
|
+
var _disposables = [];
|
|
18418
|
+
var _cleanupRegistered = false;
|
|
18419
|
+
function registerSignalCleanup() {
|
|
18420
|
+
if (_cleanupRegistered) return;
|
|
18421
|
+
_cleanupRegistered = true;
|
|
18422
|
+
for (const sig of ["SIGINT", "SIGTERM"]) {
|
|
18423
|
+
process.once(sig, async () => {
|
|
18424
|
+
for (const s of _disposables) {
|
|
18425
|
+
if (s.dispose) await s.dispose();
|
|
18426
|
+
}
|
|
18427
|
+
});
|
|
18428
|
+
}
|
|
18429
|
+
}
|
|
18430
|
+
async function initAndRegister(store, localDisposables) {
|
|
18431
|
+
const initStore = store;
|
|
18432
|
+
if (typeof initStore.initialize === "function" && initStore.initialize.length === 0) {
|
|
18433
|
+
await initStore.initialize();
|
|
18434
|
+
}
|
|
18435
|
+
const dispStore = store;
|
|
18436
|
+
if (typeof dispStore.dispose === "function") {
|
|
18437
|
+
localDisposables.push(dispStore);
|
|
18438
|
+
}
|
|
18439
|
+
}
|
|
18440
|
+
async function configureStores(stores, options = {}) {
|
|
18441
|
+
const localDisposables = [];
|
|
18442
|
+
const { schedule, checkpoint, ...regularStores } = stores;
|
|
18443
|
+
for (const [type, store] of Object.entries(regularStores)) {
|
|
18444
|
+
await initAndRegister(store, localDisposables);
|
|
18445
|
+
if (storeLatticeManager.hasLattice("default", type)) {
|
|
18446
|
+
storeLatticeManager.removeLattice("default", type);
|
|
18447
|
+
}
|
|
18448
|
+
storeLatticeManager.registerLattice("default", type, store);
|
|
18449
|
+
}
|
|
18450
|
+
if (schedule !== void 0) {
|
|
18451
|
+
await initAndRegister(schedule, localDisposables);
|
|
18452
|
+
const scheduleConfig = {
|
|
18453
|
+
name: "Default Scheduler",
|
|
18454
|
+
description: "Auto-configured schedule storage",
|
|
18455
|
+
type: "postgres",
|
|
18456
|
+
storage: schedule
|
|
18457
|
+
};
|
|
18458
|
+
registerScheduleLattice("default", scheduleConfig);
|
|
18459
|
+
}
|
|
18460
|
+
if (checkpoint !== void 0) {
|
|
18461
|
+
MemoryLatticeManager.getInstance().removeCheckpointSaver("default");
|
|
18462
|
+
registerCheckpointSaver("default", checkpoint);
|
|
18463
|
+
}
|
|
18464
|
+
if (options.customStores) {
|
|
18465
|
+
for (const [type, store] of Object.entries(options.customStores)) {
|
|
18466
|
+
await initAndRegister(store, localDisposables);
|
|
18467
|
+
const t = type;
|
|
18468
|
+
if (storeLatticeManager.hasLattice("default", t)) {
|
|
18469
|
+
storeLatticeManager.removeLattice("default", t);
|
|
18470
|
+
}
|
|
18471
|
+
storeLatticeManager.registerLattice("default", t, store);
|
|
18472
|
+
}
|
|
18473
|
+
}
|
|
18474
|
+
if (options.autoDisposeStores) {
|
|
18475
|
+
registerSignalCleanup();
|
|
18476
|
+
_disposables.push(...localDisposables);
|
|
18477
|
+
}
|
|
18478
|
+
return async () => {
|
|
18479
|
+
for (const s of localDisposables.reverse()) {
|
|
18480
|
+
if (s.dispose) await s.dispose();
|
|
18481
|
+
}
|
|
18482
|
+
};
|
|
18483
|
+
}
|
|
18484
|
+
|
|
18113
18485
|
// src/store_lattice/SandboxSkillStore.ts
|
|
18114
18486
|
function parseFrontmatter2(content) {
|
|
18115
18487
|
const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/;
|
|
@@ -22643,6 +23015,7 @@ function clearEncryptionKeyCache() {
|
|
|
22643
23015
|
CompositeBackend,
|
|
22644
23016
|
ConsoleLoggerClient,
|
|
22645
23017
|
CustomMetricsClient,
|
|
23018
|
+
CustomMiddlewareRegistry,
|
|
22646
23019
|
DaytonaInstance,
|
|
22647
23020
|
DaytonaProvider,
|
|
22648
23021
|
DefaultScheduleClient,
|
|
@@ -22716,6 +23089,7 @@ function clearEncryptionKeyCache() {
|
|
|
22716
23089
|
checkEmptyContent,
|
|
22717
23090
|
clearEncryptionKeyCache,
|
|
22718
23091
|
computeSandboxName,
|
|
23092
|
+
configureStores,
|
|
22719
23093
|
createAgentTeam,
|
|
22720
23094
|
createExecuteSqlQueryTool,
|
|
22721
23095
|
createFileData,
|