@probelabs/probe 0.6.0-rc125 → 0.6.0-rc126
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/build/agent/ProbeAgent.js +105 -8
- package/build/agent/hooks/HookManager.js +146 -0
- package/build/agent/hooks/index.js +1 -0
- package/build/agent/index.js +328 -14
- package/build/agent/storage/InMemoryStorageAdapter.js +49 -0
- package/build/agent/storage/StorageAdapter.js +51 -0
- package/build/agent/storage/index.js +2 -0
- package/build/index.js +8 -0
- package/cjs/agent/ProbeAgent.cjs +345 -31
- package/cjs/index.cjs +353 -31
- package/index.d.ts +95 -0
- package/package.json +1 -1
- package/src/agent/ProbeAgent.js +105 -8
- package/src/agent/hooks/HookManager.js +146 -0
- package/src/agent/hooks/index.js +1 -0
- package/src/agent/storage/InMemoryStorageAdapter.js +49 -0
- package/src/agent/storage/StorageAdapter.js +51 -0
- package/src/agent/storage/index.js +2 -0
- package/src/index.js +8 -0
package/build/agent/index.js
CHANGED
|
@@ -556,7 +556,7 @@ var init_BytePairEncodingCore = __esm({
|
|
|
556
556
|
var chatEnabledModels;
|
|
557
557
|
var init_modelsChatEnabled_gen = __esm({
|
|
558
558
|
"node_modules/gpt-tokenizer/esm/modelsChatEnabled.gen.js"() {
|
|
559
|
-
chatEnabledModels = ["chatgpt-4o-latest", "codex-mini-latest", "computer-use-preview", "computer-use-preview-2025-03-11", "gpt-3.5", "gpt-3.5-0301", "gpt-3.5-turbo", "gpt-3.5-turbo-0125", "gpt-3.5-turbo-0613", "gpt-3.5-turbo-1106", "gpt-3.5-turbo-16k-0613", "gpt-3.5-turbo-instruct", "gpt-4", "gpt-4-0125-preview", "gpt-4-0314", "gpt-4-0613", "gpt-4-1106-preview", "gpt-4-1106-vision-preview", "gpt-4-32k", "gpt-4-turbo", "gpt-4-turbo-2024-04-09", "gpt-4-turbo-preview", "gpt-4.1", "gpt-4.1-2025-04-14", "gpt-4.1-mini", "gpt-4.1-mini-2025-04-14", "gpt-4.1-nano", "gpt-4.1-nano-2025-04-14", "gpt-4.5-preview", "gpt-4.5-preview-2025-02-27", "gpt-4o", "gpt-4o-2024-05-13", "gpt-4o-2024-08-06", "gpt-4o-2024-11-20", "gpt-4o-audio-preview", "gpt-4o-audio-preview-2024-10-01", "gpt-4o-audio-preview-2024-12-17", "gpt-4o-audio-preview-2025-06-03", "gpt-4o-mini", "gpt-4o-mini-2024-07-18", "gpt-4o-mini-audio-preview", "gpt-4o-mini-audio-preview-2024-12-17", "gpt-4o-mini-search-preview", "gpt-4o-mini-search-preview-2025-03-11", "gpt-4o-search-preview", "gpt-4o-search-preview-2025-03-11", "o1", "o1-2024-12-17", "o1-mini", "o1-mini-2024-09-12", "o1-preview", "o1-preview-2024-09-12", "o1-pro", "o1-pro-2025-03-19", "o3", "o3-2025-04-16", "o3-mini", "o3-mini-2025-01-31", "o3-pro", "o3-pro-2025-06-10", "o4-mini", "o4-mini-2025-04-16"];
|
|
559
|
+
chatEnabledModels = ["chatgpt-4o-latest", "codex-mini-latest", "computer-use-preview", "computer-use-preview-2025-03-11", "gpt-3.5", "gpt-3.5-0301", "gpt-3.5-turbo", "gpt-3.5-turbo-0125", "gpt-3.5-turbo-0613", "gpt-3.5-turbo-1106", "gpt-3.5-turbo-16k-0613", "gpt-3.5-turbo-instruct", "gpt-4", "gpt-4-0125-preview", "gpt-4-0314", "gpt-4-0613", "gpt-4-1106-preview", "gpt-4-1106-vision-preview", "gpt-4-32k", "gpt-4-turbo", "gpt-4-turbo-2024-04-09", "gpt-4-turbo-preview", "gpt-4.1", "gpt-4.1-2025-04-14", "gpt-4.1-mini", "gpt-4.1-mini-2025-04-14", "gpt-4.1-nano", "gpt-4.1-nano-2025-04-14", "gpt-4.5-preview", "gpt-4.5-preview-2025-02-27", "gpt-4o", "gpt-4o-2024-05-13", "gpt-4o-2024-08-06", "gpt-4o-2024-11-20", "gpt-4o-audio-preview", "gpt-4o-audio-preview-2024-10-01", "gpt-4o-audio-preview-2024-12-17", "gpt-4o-audio-preview-2025-06-03", "gpt-4o-mini", "gpt-4o-mini-2024-07-18", "gpt-4o-mini-audio-preview", "gpt-4o-mini-audio-preview-2024-12-17", "gpt-4o-mini-search-preview", "gpt-4o-mini-search-preview-2025-03-11", "gpt-4o-search-preview", "gpt-4o-search-preview-2025-03-11", "gpt-5", "gpt-5-2025-08-07", "gpt-5-chat-latest", "gpt-5-codex", "gpt-5-mini", "gpt-5-mini-2025-08-07", "gpt-5-nano", "gpt-5-nano-2025-08-07", "gpt-5-pro", "gpt-5-pro-2025-10-06", "gpt-audio", "gpt-audio-2025-08-28", "gpt-audio-mini", "gpt-audio-mini-2025-10-06", "gpt-oss-120b", "gpt-oss-20b", "o1", "o1-2024-12-17", "o1-mini", "o1-mini-2024-09-12", "o1-preview", "o1-preview-2024-09-12", "o1-pro", "o1-pro-2025-03-19", "o3", "o3-2025-04-16", "o3-deep-research", "o3-deep-research-2025-06-26", "o3-mini", "o3-mini-2025-01-31", "o3-pro", "o3-pro-2025-06-10", "o4-mini", "o4-mini-2025-04-16", "o4-mini-deep-research", "o4-mini-deep-research-2025-06-26"];
|
|
560
560
|
}
|
|
561
561
|
});
|
|
562
562
|
|
|
@@ -952,8 +952,9 @@ var init_GptEncoding = __esm({
|
|
|
952
952
|
* Returns tokens assuming the 'gpt-3.5-turbo-0301' / 'gpt-4-0314' format.
|
|
953
953
|
* Based on OpenAI's guidelines: https://github.com/openai/openai-python/blob/main/chatml.md
|
|
954
954
|
* Also mentioned in section 6 of this document: https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb
|
|
955
|
+
* @param encodeOptions Options controlling how special tokens are handled.
|
|
955
956
|
*/
|
|
956
|
-
*encodeChatGenerator(chat, model = this.modelName) {
|
|
957
|
+
*encodeChatGenerator(chat, model = this.modelName, encodeOptions) {
|
|
957
958
|
if (!model) {
|
|
958
959
|
throw new Error("Model name must be provided either during initialization or passed in to the method.");
|
|
959
960
|
}
|
|
@@ -979,12 +980,12 @@ var init_GptEncoding = __esm({
|
|
|
979
980
|
if (encodedRoleSeparator.length > 0) {
|
|
980
981
|
yield encodedRoleSeparator;
|
|
981
982
|
}
|
|
982
|
-
yield* this.encodeGenerator(content);
|
|
983
|
+
yield* this.encodeGenerator(content, encodeOptions);
|
|
983
984
|
yield [chatEndToken];
|
|
984
985
|
yield encodedMessageSeparator;
|
|
985
986
|
}
|
|
986
987
|
yield [chatStartToken];
|
|
987
|
-
yield* this.encodeGenerator("assistant");
|
|
988
|
+
yield* this.encodeGenerator("assistant", encodeOptions);
|
|
988
989
|
if (encodedRoleSeparator.length > 0) {
|
|
989
990
|
yield encodedRoleSeparator;
|
|
990
991
|
}
|
|
@@ -995,15 +996,20 @@ var init_GptEncoding = __esm({
|
|
|
995
996
|
* Returns tokens assuming the 'gpt-3.5-turbo-0301' / 'gpt-4-0314' format.
|
|
996
997
|
* Based on OpenAI's guidelines: https://github.com/openai/openai-python/blob/main/chatml.md
|
|
997
998
|
* Also mentioned in section 6 of this document: https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb
|
|
999
|
+
* @param encodeOptions Options controlling how special tokens are handled.
|
|
998
1000
|
*/
|
|
999
|
-
encodeChat(chat, model = this.modelName) {
|
|
1000
|
-
return [...this.encodeChatGenerator(chat, model)].flat();
|
|
1001
|
+
encodeChat(chat, model = this.modelName, encodeOptions) {
|
|
1002
|
+
return [...this.encodeChatGenerator(chat, model, encodeOptions)].flat();
|
|
1001
1003
|
}
|
|
1002
1004
|
/**
|
|
1005
|
+
* Checks whether the provided input stays within the provided token limit.
|
|
1006
|
+
* @param input The string or chat messages to evaluate.
|
|
1007
|
+
* @param tokenLimit The maximum allowed number of tokens.
|
|
1008
|
+
* @param encodeOptions Options controlling how special tokens are handled.
|
|
1003
1009
|
* @returns {false | number} false if token limit is exceeded, otherwise the number of tokens
|
|
1004
1010
|
*/
|
|
1005
|
-
isWithinTokenLimit(input, tokenLimit) {
|
|
1006
|
-
const tokenGenerator = typeof input === "string" ? this.encodeGenerator(input) : this.encodeChatGenerator(input);
|
|
1011
|
+
isWithinTokenLimit(input, tokenLimit, encodeOptions) {
|
|
1012
|
+
const tokenGenerator = typeof input === "string" ? this.encodeGenerator(input, encodeOptions) : this.encodeChatGenerator(input, void 0, encodeOptions);
|
|
1007
1013
|
let count = 0;
|
|
1008
1014
|
for (const tokens of tokenGenerator) {
|
|
1009
1015
|
count += tokens.length;
|
|
@@ -1015,6 +1021,8 @@ var init_GptEncoding = __esm({
|
|
|
1015
1021
|
}
|
|
1016
1022
|
/**
|
|
1017
1023
|
* Counts the number of tokens in the input.
|
|
1024
|
+
* @param input The string or chat messages to evaluate.
|
|
1025
|
+
* @param encodeOptions Options controlling how special tokens are handled.
|
|
1018
1026
|
* @returns {number} The number of tokens.
|
|
1019
1027
|
*/
|
|
1020
1028
|
countTokens(input, encodeOptions) {
|
|
@@ -1028,7 +1036,7 @@ var init_GptEncoding = __esm({
|
|
|
1028
1036
|
}
|
|
1029
1037
|
return this.bytePairEncodingCoreProcessor.countNative(input, specialTokenConfig.allowedSpecial);
|
|
1030
1038
|
}
|
|
1031
|
-
const tokenGenerator = this.encodeChatGenerator(input);
|
|
1039
|
+
const tokenGenerator = this.encodeChatGenerator(input, void 0, encodeOptions);
|
|
1032
1040
|
let count = 0;
|
|
1033
1041
|
for (const tokens of tokenGenerator) {
|
|
1034
1042
|
count += tokens.length;
|
|
@@ -1466,6 +1474,226 @@ var init_tokenCounter = __esm({
|
|
|
1466
1474
|
}
|
|
1467
1475
|
});
|
|
1468
1476
|
|
|
1477
|
+
// src/agent/storage/StorageAdapter.js
|
|
1478
|
+
var StorageAdapter;
|
|
1479
|
+
var init_StorageAdapter = __esm({
|
|
1480
|
+
"src/agent/storage/StorageAdapter.js"() {
|
|
1481
|
+
"use strict";
|
|
1482
|
+
StorageAdapter = class {
|
|
1483
|
+
/**
|
|
1484
|
+
* Load conversation history for a session
|
|
1485
|
+
* @param {string} sessionId - Session identifier
|
|
1486
|
+
* @returns {Promise<Array<Object>>} Array of message objects with {role, content, ...}
|
|
1487
|
+
*/
|
|
1488
|
+
async loadHistory(sessionId) {
|
|
1489
|
+
throw new Error("StorageAdapter.loadHistory() must be implemented by subclass");
|
|
1490
|
+
}
|
|
1491
|
+
/**
|
|
1492
|
+
* Save a message to storage
|
|
1493
|
+
* @param {string} sessionId - Session identifier
|
|
1494
|
+
* @param {Object} message - Message object { role, content, ... }
|
|
1495
|
+
* @returns {Promise<void>}
|
|
1496
|
+
*/
|
|
1497
|
+
async saveMessage(sessionId, message) {
|
|
1498
|
+
throw new Error("StorageAdapter.saveMessage() must be implemented by subclass");
|
|
1499
|
+
}
|
|
1500
|
+
/**
|
|
1501
|
+
* Clear history for a session
|
|
1502
|
+
* @param {string} sessionId - Session identifier
|
|
1503
|
+
* @returns {Promise<void>}
|
|
1504
|
+
*/
|
|
1505
|
+
async clearHistory(sessionId) {
|
|
1506
|
+
throw new Error("StorageAdapter.clearHistory() must be implemented by subclass");
|
|
1507
|
+
}
|
|
1508
|
+
/**
|
|
1509
|
+
* Get session metadata (optional)
|
|
1510
|
+
* @param {string} sessionId - Session identifier
|
|
1511
|
+
* @returns {Promise<Object|null>} Session metadata or null
|
|
1512
|
+
*/
|
|
1513
|
+
async getSessionMetadata(sessionId) {
|
|
1514
|
+
return null;
|
|
1515
|
+
}
|
|
1516
|
+
/**
|
|
1517
|
+
* Update session activity timestamp (optional)
|
|
1518
|
+
* @param {string} sessionId - Session identifier
|
|
1519
|
+
* @returns {Promise<void>}
|
|
1520
|
+
*/
|
|
1521
|
+
async updateSessionActivity(sessionId) {
|
|
1522
|
+
}
|
|
1523
|
+
};
|
|
1524
|
+
}
|
|
1525
|
+
});
|
|
1526
|
+
|
|
1527
|
+
// src/agent/storage/InMemoryStorageAdapter.js
|
|
1528
|
+
var InMemoryStorageAdapter;
|
|
1529
|
+
var init_InMemoryStorageAdapter = __esm({
|
|
1530
|
+
"src/agent/storage/InMemoryStorageAdapter.js"() {
|
|
1531
|
+
"use strict";
|
|
1532
|
+
init_StorageAdapter();
|
|
1533
|
+
InMemoryStorageAdapter = class extends StorageAdapter {
|
|
1534
|
+
constructor() {
|
|
1535
|
+
super();
|
|
1536
|
+
this.sessions = /* @__PURE__ */ new Map();
|
|
1537
|
+
}
|
|
1538
|
+
async loadHistory(sessionId) {
|
|
1539
|
+
const session = this.sessions.get(sessionId);
|
|
1540
|
+
return session ? session.messages : [];
|
|
1541
|
+
}
|
|
1542
|
+
async saveMessage(sessionId, message) {
|
|
1543
|
+
if (!this.sessions.has(sessionId)) {
|
|
1544
|
+
this.sessions.set(sessionId, {
|
|
1545
|
+
messages: [],
|
|
1546
|
+
metadata: {
|
|
1547
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1548
|
+
lastActivity: (/* @__PURE__ */ new Date()).toISOString()
|
|
1549
|
+
}
|
|
1550
|
+
});
|
|
1551
|
+
}
|
|
1552
|
+
const session = this.sessions.get(sessionId);
|
|
1553
|
+
session.messages.push(message);
|
|
1554
|
+
session.metadata.lastActivity = (/* @__PURE__ */ new Date()).toISOString();
|
|
1555
|
+
}
|
|
1556
|
+
async clearHistory(sessionId) {
|
|
1557
|
+
this.sessions.delete(sessionId);
|
|
1558
|
+
}
|
|
1559
|
+
async getSessionMetadata(sessionId) {
|
|
1560
|
+
const session = this.sessions.get(sessionId);
|
|
1561
|
+
return session ? session.metadata : null;
|
|
1562
|
+
}
|
|
1563
|
+
async updateSessionActivity(sessionId) {
|
|
1564
|
+
const session = this.sessions.get(sessionId);
|
|
1565
|
+
if (session) {
|
|
1566
|
+
session.metadata.lastActivity = (/* @__PURE__ */ new Date()).toISOString();
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
};
|
|
1570
|
+
}
|
|
1571
|
+
});
|
|
1572
|
+
|
|
1573
|
+
// src/agent/hooks/HookManager.js
|
|
1574
|
+
var HookManager, HOOK_TYPES;
|
|
1575
|
+
var init_HookManager = __esm({
|
|
1576
|
+
"src/agent/hooks/HookManager.js"() {
|
|
1577
|
+
"use strict";
|
|
1578
|
+
HookManager = class {
|
|
1579
|
+
constructor() {
|
|
1580
|
+
this.hooks = /* @__PURE__ */ new Map();
|
|
1581
|
+
}
|
|
1582
|
+
/**
|
|
1583
|
+
* Register a hook callback
|
|
1584
|
+
* @param {string} hookName - Name of the hook
|
|
1585
|
+
* @param {Function} callback - Callback function
|
|
1586
|
+
* @returns {Function} Unregister function
|
|
1587
|
+
*/
|
|
1588
|
+
on(hookName, callback) {
|
|
1589
|
+
if (!this.hooks.has(hookName)) {
|
|
1590
|
+
this.hooks.set(hookName, /* @__PURE__ */ new Set());
|
|
1591
|
+
}
|
|
1592
|
+
this.hooks.get(hookName).add(callback);
|
|
1593
|
+
return () => this.off(hookName, callback);
|
|
1594
|
+
}
|
|
1595
|
+
/**
|
|
1596
|
+
* Register a one-time hook callback
|
|
1597
|
+
* @param {string} hookName - Name of the hook
|
|
1598
|
+
* @param {Function} callback - Callback function
|
|
1599
|
+
* @returns {Function} Unregister function
|
|
1600
|
+
*/
|
|
1601
|
+
once(hookName, callback) {
|
|
1602
|
+
const wrappedCallback = async (data) => {
|
|
1603
|
+
this.off(hookName, wrappedCallback);
|
|
1604
|
+
await callback(data);
|
|
1605
|
+
};
|
|
1606
|
+
return this.on(hookName, wrappedCallback);
|
|
1607
|
+
}
|
|
1608
|
+
/**
|
|
1609
|
+
* Unregister a hook callback
|
|
1610
|
+
* @param {string} hookName - Name of the hook
|
|
1611
|
+
* @param {Function} callback - Callback function
|
|
1612
|
+
*/
|
|
1613
|
+
off(hookName, callback) {
|
|
1614
|
+
const callbacks = this.hooks.get(hookName);
|
|
1615
|
+
if (callbacks) {
|
|
1616
|
+
callbacks.delete(callback);
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
/**
|
|
1620
|
+
* Emit a hook event
|
|
1621
|
+
* @param {string} hookName - Name of the hook
|
|
1622
|
+
* @param {any} data - Data to pass to callbacks
|
|
1623
|
+
* @returns {Promise<void>}
|
|
1624
|
+
*/
|
|
1625
|
+
async emit(hookName, data) {
|
|
1626
|
+
const callbacks = this.hooks.get(hookName);
|
|
1627
|
+
if (!callbacks || callbacks.size === 0) return;
|
|
1628
|
+
const promises = Array.from(callbacks).map((callback) => {
|
|
1629
|
+
try {
|
|
1630
|
+
return Promise.resolve(callback(data));
|
|
1631
|
+
} catch (error) {
|
|
1632
|
+
return Promise.reject(error);
|
|
1633
|
+
}
|
|
1634
|
+
});
|
|
1635
|
+
const results = await Promise.allSettled(promises);
|
|
1636
|
+
results.forEach((result, index) => {
|
|
1637
|
+
if (result.status === "rejected") {
|
|
1638
|
+
console.error(`[HookManager] Error in hook "${hookName}" (callback ${index + 1}):`, result.reason);
|
|
1639
|
+
}
|
|
1640
|
+
});
|
|
1641
|
+
}
|
|
1642
|
+
/**
|
|
1643
|
+
* Clear all hooks or hooks for a specific event
|
|
1644
|
+
* @param {string} [hookName] - Optional hook name to clear
|
|
1645
|
+
*/
|
|
1646
|
+
clear(hookName) {
|
|
1647
|
+
if (hookName) {
|
|
1648
|
+
this.hooks.delete(hookName);
|
|
1649
|
+
} else {
|
|
1650
|
+
this.hooks.clear();
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
/**
|
|
1654
|
+
* Get list of registered hook names
|
|
1655
|
+
* @returns {string[]} Array of hook names
|
|
1656
|
+
*/
|
|
1657
|
+
getHookNames() {
|
|
1658
|
+
return Array.from(this.hooks.keys());
|
|
1659
|
+
}
|
|
1660
|
+
/**
|
|
1661
|
+
* Get number of callbacks for a hook
|
|
1662
|
+
* @param {string} hookName - Name of the hook
|
|
1663
|
+
* @returns {number} Number of callbacks
|
|
1664
|
+
*/
|
|
1665
|
+
getCallbackCount(hookName) {
|
|
1666
|
+
const callbacks = this.hooks.get(hookName);
|
|
1667
|
+
return callbacks ? callbacks.size : 0;
|
|
1668
|
+
}
|
|
1669
|
+
};
|
|
1670
|
+
HOOK_TYPES = {
|
|
1671
|
+
// Lifecycle hooks
|
|
1672
|
+
AGENT_INITIALIZED: "agent:initialized",
|
|
1673
|
+
AGENT_CLEANUP: "agent:cleanup",
|
|
1674
|
+
// Message hooks
|
|
1675
|
+
MESSAGE_USER: "message:user",
|
|
1676
|
+
MESSAGE_ASSISTANT: "message:assistant",
|
|
1677
|
+
MESSAGE_SYSTEM: "message:system",
|
|
1678
|
+
// Tool execution hooks
|
|
1679
|
+
TOOL_START: "tool:start",
|
|
1680
|
+
TOOL_END: "tool:end",
|
|
1681
|
+
TOOL_ERROR: "tool:error",
|
|
1682
|
+
// AI streaming hooks
|
|
1683
|
+
AI_STREAM_START: "ai:stream:start",
|
|
1684
|
+
AI_STREAM_DELTA: "ai:stream:delta",
|
|
1685
|
+
AI_STREAM_END: "ai:stream:end",
|
|
1686
|
+
// Storage hooks
|
|
1687
|
+
STORAGE_LOAD: "storage:load",
|
|
1688
|
+
STORAGE_SAVE: "storage:save",
|
|
1689
|
+
STORAGE_CLEAR: "storage:clear",
|
|
1690
|
+
// Iteration hooks
|
|
1691
|
+
ITERATION_START: "iteration:start",
|
|
1692
|
+
ITERATION_END: "iteration:end"
|
|
1693
|
+
};
|
|
1694
|
+
}
|
|
1695
|
+
});
|
|
1696
|
+
|
|
1469
1697
|
// src/directory-resolver.js
|
|
1470
1698
|
import path from "path";
|
|
1471
1699
|
import os from "os";
|
|
@@ -16121,6 +16349,23 @@ var init_probeTool = __esm({
|
|
|
16121
16349
|
}
|
|
16122
16350
|
});
|
|
16123
16351
|
|
|
16352
|
+
// src/agent/storage/index.js
|
|
16353
|
+
var init_storage = __esm({
|
|
16354
|
+
"src/agent/storage/index.js"() {
|
|
16355
|
+
"use strict";
|
|
16356
|
+
init_StorageAdapter();
|
|
16357
|
+
init_InMemoryStorageAdapter();
|
|
16358
|
+
}
|
|
16359
|
+
});
|
|
16360
|
+
|
|
16361
|
+
// src/agent/hooks/index.js
|
|
16362
|
+
var init_hooks = __esm({
|
|
16363
|
+
"src/agent/hooks/index.js"() {
|
|
16364
|
+
"use strict";
|
|
16365
|
+
init_HookManager();
|
|
16366
|
+
}
|
|
16367
|
+
});
|
|
16368
|
+
|
|
16124
16369
|
// src/index.js
|
|
16125
16370
|
var init_index = __esm({
|
|
16126
16371
|
"src/index.js"() {
|
|
@@ -16140,6 +16385,8 @@ var init_index = __esm({
|
|
|
16140
16385
|
init_ProbeAgent();
|
|
16141
16386
|
init_simpleTelemetry();
|
|
16142
16387
|
init_probeTool();
|
|
16388
|
+
init_storage();
|
|
16389
|
+
init_hooks();
|
|
16143
16390
|
}
|
|
16144
16391
|
});
|
|
16145
16392
|
|
|
@@ -47313,6 +47560,8 @@ var init_ProbeAgent = __esm({
|
|
|
47313
47560
|
"src/agent/ProbeAgent.js"() {
|
|
47314
47561
|
"use strict";
|
|
47315
47562
|
init_tokenCounter();
|
|
47563
|
+
init_InMemoryStorageAdapter();
|
|
47564
|
+
init_HookManager();
|
|
47316
47565
|
init_tools2();
|
|
47317
47566
|
init_common();
|
|
47318
47567
|
init_probeTool();
|
|
@@ -47345,6 +47594,8 @@ var init_ProbeAgent = __esm({
|
|
|
47345
47594
|
* @param {string} [options.mcpConfigPath] - Path to MCP configuration file
|
|
47346
47595
|
* @param {Object} [options.mcpConfig] - MCP configuration object (overrides mcpConfigPath)
|
|
47347
47596
|
* @param {Array} [options.mcpServers] - Deprecated, use mcpConfig instead
|
|
47597
|
+
* @param {Object} [options.storageAdapter] - Custom storage adapter for history management
|
|
47598
|
+
* @param {Object} [options.hooks] - Hook callbacks for events (e.g., {'tool:start': callback})
|
|
47348
47599
|
*/
|
|
47349
47600
|
constructor(options = {}) {
|
|
47350
47601
|
this.sessionId = options.sessionId || randomUUID4();
|
|
@@ -47358,6 +47609,13 @@ var init_ProbeAgent = __esm({
|
|
|
47358
47609
|
this.maxResponseTokens = options.maxResponseTokens || parseInt(process.env.MAX_RESPONSE_TOKENS || "0", 10) || null;
|
|
47359
47610
|
this.maxIterations = options.maxIterations || null;
|
|
47360
47611
|
this.disableMermaidValidation = !!options.disableMermaidValidation;
|
|
47612
|
+
this.storageAdapter = options.storageAdapter || new InMemoryStorageAdapter();
|
|
47613
|
+
this.hooks = new HookManager();
|
|
47614
|
+
if (options.hooks) {
|
|
47615
|
+
for (const [hookName, callback] of Object.entries(options.hooks)) {
|
|
47616
|
+
this.hooks.on(hookName, callback);
|
|
47617
|
+
}
|
|
47618
|
+
}
|
|
47361
47619
|
this.enableBash = !!options.enableBash;
|
|
47362
47620
|
this.bashConfig = options.bashConfig || {};
|
|
47363
47621
|
if (options.allowedFolders && Array.isArray(options.allowedFolders)) {
|
|
@@ -47391,9 +47649,23 @@ var init_ProbeAgent = __esm({
|
|
|
47391
47649
|
}
|
|
47392
47650
|
/**
|
|
47393
47651
|
* Initialize the agent asynchronously (must be called after constructor)
|
|
47394
|
-
* This method initializes MCP and merges MCP tools into the tool list
|
|
47652
|
+
* This method initializes MCP and merges MCP tools into the tool list, and loads history from storage
|
|
47395
47653
|
*/
|
|
47396
47654
|
async initialize() {
|
|
47655
|
+
try {
|
|
47656
|
+
const history = await this.storageAdapter.loadHistory(this.sessionId);
|
|
47657
|
+
this.history = history;
|
|
47658
|
+
if (this.debug && history.length > 0) {
|
|
47659
|
+
console.log(`[DEBUG] Loaded ${history.length} messages from storage for session ${this.sessionId}`);
|
|
47660
|
+
}
|
|
47661
|
+
await this.hooks.emit(HOOK_TYPES.STORAGE_LOAD, {
|
|
47662
|
+
sessionId: this.sessionId,
|
|
47663
|
+
messages: history
|
|
47664
|
+
});
|
|
47665
|
+
} catch (error) {
|
|
47666
|
+
console.error(`[ERROR] Failed to load history from storage:`, error);
|
|
47667
|
+
this.history = [];
|
|
47668
|
+
}
|
|
47397
47669
|
if (this.enableMcp && !this._mcpInitialized) {
|
|
47398
47670
|
this._mcpInitialized = true;
|
|
47399
47671
|
try {
|
|
@@ -47426,6 +47698,10 @@ var init_ProbeAgent = __esm({
|
|
|
47426
47698
|
this.mcpBridge = null;
|
|
47427
47699
|
}
|
|
47428
47700
|
}
|
|
47701
|
+
await this.hooks.emit(HOOK_TYPES.AGENT_INITIALIZED, {
|
|
47702
|
+
sessionId: this.sessionId,
|
|
47703
|
+
agent: this
|
|
47704
|
+
});
|
|
47429
47705
|
}
|
|
47430
47706
|
/**
|
|
47431
47707
|
* Initialize tools with configuration
|
|
@@ -47477,7 +47753,7 @@ var init_ProbeAgent = __esm({
|
|
|
47477
47753
|
}
|
|
47478
47754
|
const anthropicApiKey = process.env.ANTHROPIC_API_KEY;
|
|
47479
47755
|
const openaiApiKey = process.env.OPENAI_API_KEY;
|
|
47480
|
-
const googleApiKey = process.env.GOOGLE_API_KEY;
|
|
47756
|
+
const googleApiKey = process.env.GOOGLE_GENERATIVE_AI_API_KEY || process.env.GOOGLE_API_KEY;
|
|
47481
47757
|
const awsAccessKeyId = process.env.AWS_ACCESS_KEY_ID;
|
|
47482
47758
|
const awsSecretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
|
|
47483
47759
|
const awsRegion = process.env.AWS_REGION;
|
|
@@ -47525,7 +47801,7 @@ var init_ProbeAgent = __esm({
|
|
|
47525
47801
|
} else if (awsAccessKeyId && awsSecretAccessKey && awsRegion || awsApiKey) {
|
|
47526
47802
|
this.initializeBedrockModel(awsAccessKeyId, awsSecretAccessKey, awsRegion, awsSessionToken, awsApiKey, awsBedrockBaseUrl, modelName);
|
|
47527
47803
|
} else {
|
|
47528
|
-
throw new Error("No API key provided. Please set ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_API_KEY, AWS credentials (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION), or AWS_BEDROCK_API_KEY environment variables.");
|
|
47804
|
+
throw new Error("No API key provided. Please set ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY (or GOOGLE_API_KEY), AWS credentials (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION), or AWS_BEDROCK_API_KEY environment variables.");
|
|
47529
47805
|
}
|
|
47530
47806
|
}
|
|
47531
47807
|
/**
|
|
@@ -48163,6 +48439,12 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
48163
48439
|
options = schemaOrOptions || {};
|
|
48164
48440
|
}
|
|
48165
48441
|
try {
|
|
48442
|
+
const oldHistoryLength = this.history.length;
|
|
48443
|
+
await this.hooks.emit(HOOK_TYPES.MESSAGE_USER, {
|
|
48444
|
+
sessionId: this.sessionId,
|
|
48445
|
+
message,
|
|
48446
|
+
images
|
|
48447
|
+
});
|
|
48166
48448
|
const systemMessage = await this.getSystemMessage();
|
|
48167
48449
|
let userMessage = { role: "user", content: message.trim() };
|
|
48168
48450
|
if (images && images.length > 0) {
|
|
@@ -48248,6 +48530,9 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
48248
48530
|
});
|
|
48249
48531
|
for await (const delta of result.textStream) {
|
|
48250
48532
|
assistantResponseContent += delta;
|
|
48533
|
+
if (options.onStream) {
|
|
48534
|
+
options.onStream(delta);
|
|
48535
|
+
}
|
|
48251
48536
|
}
|
|
48252
48537
|
const usage = await result.usage;
|
|
48253
48538
|
if (usage) {
|
|
@@ -48312,6 +48597,13 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
48312
48597
|
const validation = attemptCompletionSchema.safeParse(params);
|
|
48313
48598
|
if (validation.success) {
|
|
48314
48599
|
finalResult = validation.data.result;
|
|
48600
|
+
if (options.onStream && finalResult) {
|
|
48601
|
+
const chunkSize = 50;
|
|
48602
|
+
for (let i = 0; i < finalResult.length; i += chunkSize) {
|
|
48603
|
+
const chunk = finalResult.slice(i, Math.min(i + chunkSize, finalResult.length));
|
|
48604
|
+
options.onStream(chunk);
|
|
48605
|
+
}
|
|
48606
|
+
}
|
|
48315
48607
|
if (this.debug) console.log(`[DEBUG] Task completed successfully with result: ${finalResult.substring(0, 100)}...`);
|
|
48316
48608
|
} else {
|
|
48317
48609
|
console.error(`[ERROR] Invalid attempt_completion parameters:`, validation.error);
|
|
@@ -48386,7 +48678,9 @@ ${toolResultContent}
|
|
|
48386
48678
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
48387
48679
|
name: toolName,
|
|
48388
48680
|
args: toolParams,
|
|
48389
|
-
status: "started"
|
|
48681
|
+
status: "started",
|
|
48682
|
+
pauseStream: true
|
|
48683
|
+
// Signal to pause text streaming
|
|
48390
48684
|
});
|
|
48391
48685
|
const executeToolCall = async () => {
|
|
48392
48686
|
if (toolName === "delegate") {
|
|
@@ -48570,6 +48864,18 @@ IMPORTANT: When using <attempt_complete>, this must be the ONLY content in your
|
|
|
48570
48864
|
}
|
|
48571
48865
|
}
|
|
48572
48866
|
this.tokenCounter.updateHistory(this.history);
|
|
48867
|
+
try {
|
|
48868
|
+
const messagesToSave = currentMessages.slice(oldHistoryLength);
|
|
48869
|
+
for (const message2 of messagesToSave) {
|
|
48870
|
+
await this.storageAdapter.saveMessage(this.sessionId, message2);
|
|
48871
|
+
await this.hooks.emit(HOOK_TYPES.STORAGE_SAVE, {
|
|
48872
|
+
sessionId: this.sessionId,
|
|
48873
|
+
message: message2
|
|
48874
|
+
});
|
|
48875
|
+
}
|
|
48876
|
+
} catch (error) {
|
|
48877
|
+
console.error(`[ERROR] Failed to save messages to storage:`, error);
|
|
48878
|
+
}
|
|
48573
48879
|
const reachedMaxIterations = currentIteration >= maxIterations && !completionAttempted;
|
|
48574
48880
|
if (options.schema && !options._schemaFormatted && !completionAttempted && !reachedMaxIterations) {
|
|
48575
48881
|
if (this.debug) {
|
|
@@ -48934,10 +49240,18 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
48934
49240
|
/**
|
|
48935
49241
|
* Clear conversation history and reset counters
|
|
48936
49242
|
*/
|
|
48937
|
-
clearHistory() {
|
|
49243
|
+
async clearHistory() {
|
|
49244
|
+
try {
|
|
49245
|
+
await this.storageAdapter.clearHistory(this.sessionId);
|
|
49246
|
+
} catch (error) {
|
|
49247
|
+
console.error(`[ERROR] Failed to clear history in storage:`, error);
|
|
49248
|
+
}
|
|
48938
49249
|
this.history = [];
|
|
48939
49250
|
this.tokenCounter.clear();
|
|
48940
49251
|
clearToolExecutionData(this.sessionId);
|
|
49252
|
+
await this.hooks.emit(HOOK_TYPES.STORAGE_CLEAR, {
|
|
49253
|
+
sessionId: this.sessionId
|
|
49254
|
+
});
|
|
48941
49255
|
if (this.debug) {
|
|
48942
49256
|
console.log(`[DEBUG] Cleared conversation history and reset counters for session ${this.sessionId}`);
|
|
48943
49257
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { StorageAdapter } from './StorageAdapter.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Default in-memory storage adapter
|
|
5
|
+
* This is the default behavior - stores history in a Map in memory
|
|
6
|
+
*/
|
|
7
|
+
export class InMemoryStorageAdapter extends StorageAdapter {
|
|
8
|
+
constructor() {
|
|
9
|
+
super();
|
|
10
|
+
this.sessions = new Map(); // sessionId -> {messages: [], metadata: {}}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async loadHistory(sessionId) {
|
|
14
|
+
const session = this.sessions.get(sessionId);
|
|
15
|
+
return session ? session.messages : [];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async saveMessage(sessionId, message) {
|
|
19
|
+
if (!this.sessions.has(sessionId)) {
|
|
20
|
+
this.sessions.set(sessionId, {
|
|
21
|
+
messages: [],
|
|
22
|
+
metadata: {
|
|
23
|
+
createdAt: new Date().toISOString(),
|
|
24
|
+
lastActivity: new Date().toISOString()
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const session = this.sessions.get(sessionId);
|
|
30
|
+
session.messages.push(message);
|
|
31
|
+
session.metadata.lastActivity = new Date().toISOString();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async clearHistory(sessionId) {
|
|
35
|
+
this.sessions.delete(sessionId);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async getSessionMetadata(sessionId) {
|
|
39
|
+
const session = this.sessions.get(sessionId);
|
|
40
|
+
return session ? session.metadata : null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async updateSessionActivity(sessionId) {
|
|
44
|
+
const session = this.sessions.get(sessionId);
|
|
45
|
+
if (session) {
|
|
46
|
+
session.metadata.lastActivity = new Date().toISOString();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base class for storage adapters
|
|
3
|
+
* Implement this interface to provide custom storage backends for ProbeAgent history
|
|
4
|
+
*/
|
|
5
|
+
export class StorageAdapter {
|
|
6
|
+
/**
|
|
7
|
+
* Load conversation history for a session
|
|
8
|
+
* @param {string} sessionId - Session identifier
|
|
9
|
+
* @returns {Promise<Array<Object>>} Array of message objects with {role, content, ...}
|
|
10
|
+
*/
|
|
11
|
+
async loadHistory(sessionId) {
|
|
12
|
+
throw new Error('StorageAdapter.loadHistory() must be implemented by subclass');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Save a message to storage
|
|
17
|
+
* @param {string} sessionId - Session identifier
|
|
18
|
+
* @param {Object} message - Message object { role, content, ... }
|
|
19
|
+
* @returns {Promise<void>}
|
|
20
|
+
*/
|
|
21
|
+
async saveMessage(sessionId, message) {
|
|
22
|
+
throw new Error('StorageAdapter.saveMessage() must be implemented by subclass');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Clear history for a session
|
|
27
|
+
* @param {string} sessionId - Session identifier
|
|
28
|
+
* @returns {Promise<void>}
|
|
29
|
+
*/
|
|
30
|
+
async clearHistory(sessionId) {
|
|
31
|
+
throw new Error('StorageAdapter.clearHistory() must be implemented by subclass');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Get session metadata (optional)
|
|
36
|
+
* @param {string} sessionId - Session identifier
|
|
37
|
+
* @returns {Promise<Object|null>} Session metadata or null
|
|
38
|
+
*/
|
|
39
|
+
async getSessionMetadata(sessionId) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Update session activity timestamp (optional)
|
|
45
|
+
* @param {string} sessionId - Session identifier
|
|
46
|
+
* @returns {Promise<void>}
|
|
47
|
+
*/
|
|
48
|
+
async updateSessionActivity(sessionId) {
|
|
49
|
+
// Optional - implement if you want to track session activity
|
|
50
|
+
}
|
|
51
|
+
}
|
package/build/index.js
CHANGED
|
@@ -36,6 +36,8 @@ import { bashTool } from './tools/bash.js';
|
|
|
36
36
|
import { ProbeAgent } from './agent/ProbeAgent.js';
|
|
37
37
|
import { SimpleTelemetry, SimpleAppTracer, initializeSimpleTelemetryFromOptions } from './agent/simpleTelemetry.js';
|
|
38
38
|
import { listFilesToolInstance, searchFilesToolInstance } from './agent/probeTool.js';
|
|
39
|
+
import { StorageAdapter, InMemoryStorageAdapter } from './agent/storage/index.js';
|
|
40
|
+
import { HookManager, HOOK_TYPES } from './agent/hooks/index.js';
|
|
39
41
|
|
|
40
42
|
export {
|
|
41
43
|
search,
|
|
@@ -50,6 +52,12 @@ export {
|
|
|
50
52
|
DEFAULT_SYSTEM_MESSAGE,
|
|
51
53
|
// Export AI Agent (NEW!)
|
|
52
54
|
ProbeAgent,
|
|
55
|
+
// Export storage adapters
|
|
56
|
+
StorageAdapter,
|
|
57
|
+
InMemoryStorageAdapter,
|
|
58
|
+
// Export hooks
|
|
59
|
+
HookManager,
|
|
60
|
+
HOOK_TYPES,
|
|
53
61
|
// Export telemetry classes
|
|
54
62
|
SimpleTelemetry,
|
|
55
63
|
SimpleAppTracer,
|