@probelabs/probe 0.6.0-rc125 → 0.6.0-rc127

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.
@@ -16640,7 +16640,7 @@ var require_package = __commonJS({
16640
16640
  module2.exports = {
16641
16641
  name: "@aws-sdk/client-bedrock-runtime",
16642
16642
  description: "AWS SDK for JavaScript Bedrock Runtime Client for Node.js, Browser and React Native",
16643
- version: "3.906.0",
16643
+ version: "3.907.0",
16644
16644
  scripts: {
16645
16645
  build: "concurrently 'yarn:build:cjs' 'yarn:build:es' 'yarn:build:types'",
16646
16646
  "build:cjs": "node ../../scripts/compilation/inline client-bedrock-runtime",
@@ -16659,21 +16659,21 @@ var require_package = __commonJS({
16659
16659
  dependencies: {
16660
16660
  "@aws-crypto/sha256-browser": "5.2.0",
16661
16661
  "@aws-crypto/sha256-js": "5.2.0",
16662
- "@aws-sdk/core": "3.906.0",
16663
- "@aws-sdk/credential-provider-node": "3.906.0",
16662
+ "@aws-sdk/core": "3.907.0",
16663
+ "@aws-sdk/credential-provider-node": "3.907.0",
16664
16664
  "@aws-sdk/eventstream-handler-node": "3.901.0",
16665
16665
  "@aws-sdk/middleware-eventstream": "3.901.0",
16666
16666
  "@aws-sdk/middleware-host-header": "3.901.0",
16667
16667
  "@aws-sdk/middleware-logger": "3.901.0",
16668
16668
  "@aws-sdk/middleware-recursion-detection": "3.901.0",
16669
- "@aws-sdk/middleware-user-agent": "3.906.0",
16669
+ "@aws-sdk/middleware-user-agent": "3.907.0",
16670
16670
  "@aws-sdk/middleware-websocket": "3.901.0",
16671
16671
  "@aws-sdk/region-config-resolver": "3.901.0",
16672
- "@aws-sdk/token-providers": "3.906.0",
16672
+ "@aws-sdk/token-providers": "3.907.0",
16673
16673
  "@aws-sdk/types": "3.901.0",
16674
16674
  "@aws-sdk/util-endpoints": "3.901.0",
16675
- "@aws-sdk/util-user-agent-browser": "3.901.0",
16676
- "@aws-sdk/util-user-agent-node": "3.906.0",
16675
+ "@aws-sdk/util-user-agent-browser": "3.907.0",
16676
+ "@aws-sdk/util-user-agent-node": "3.907.0",
16677
16677
  "@smithy/config-resolver": "^4.3.0",
16678
16678
  "@smithy/core": "^3.14.0",
16679
16679
  "@smithy/eventstream-serde-browser": "^4.2.0",
@@ -17421,7 +17421,7 @@ var init_package = __esm({
17421
17421
  "node_modules/@aws-sdk/nested-clients/package.json"() {
17422
17422
  package_default = {
17423
17423
  name: "@aws-sdk/nested-clients",
17424
- version: "3.906.0",
17424
+ version: "3.907.0",
17425
17425
  description: "Nested clients for AWS SDK packages.",
17426
17426
  main: "./dist-cjs/index.js",
17427
17427
  module: "./dist-es/index.js",
@@ -17450,16 +17450,16 @@ var init_package = __esm({
17450
17450
  dependencies: {
17451
17451
  "@aws-crypto/sha256-browser": "5.2.0",
17452
17452
  "@aws-crypto/sha256-js": "5.2.0",
17453
- "@aws-sdk/core": "3.906.0",
17453
+ "@aws-sdk/core": "3.907.0",
17454
17454
  "@aws-sdk/middleware-host-header": "3.901.0",
17455
17455
  "@aws-sdk/middleware-logger": "3.901.0",
17456
17456
  "@aws-sdk/middleware-recursion-detection": "3.901.0",
17457
- "@aws-sdk/middleware-user-agent": "3.906.0",
17457
+ "@aws-sdk/middleware-user-agent": "3.907.0",
17458
17458
  "@aws-sdk/region-config-resolver": "3.901.0",
17459
17459
  "@aws-sdk/types": "3.901.0",
17460
17460
  "@aws-sdk/util-endpoints": "3.901.0",
17461
- "@aws-sdk/util-user-agent-browser": "3.901.0",
17462
- "@aws-sdk/util-user-agent-node": "3.906.0",
17461
+ "@aws-sdk/util-user-agent-browser": "3.907.0",
17462
+ "@aws-sdk/util-user-agent-node": "3.907.0",
17463
17463
  "@smithy/config-resolver": "^4.3.0",
17464
17464
  "@smithy/core": "^3.14.0",
17465
17465
  "@smithy/fetch-http-handler": "^5.3.0",
@@ -18896,7 +18896,7 @@ var require_package2 = __commonJS({
18896
18896
  module2.exports = {
18897
18897
  name: "@aws-sdk/client-sso",
18898
18898
  description: "AWS SDK for JavaScript Sso Client for Node.js, Browser and React Native",
18899
- version: "3.906.0",
18899
+ version: "3.907.0",
18900
18900
  scripts: {
18901
18901
  build: "concurrently 'yarn:build:cjs' 'yarn:build:es' 'yarn:build:types'",
18902
18902
  "build:cjs": "node ../../scripts/compilation/inline client-sso",
@@ -18915,16 +18915,16 @@ var require_package2 = __commonJS({
18915
18915
  dependencies: {
18916
18916
  "@aws-crypto/sha256-browser": "5.2.0",
18917
18917
  "@aws-crypto/sha256-js": "5.2.0",
18918
- "@aws-sdk/core": "3.906.0",
18918
+ "@aws-sdk/core": "3.907.0",
18919
18919
  "@aws-sdk/middleware-host-header": "3.901.0",
18920
18920
  "@aws-sdk/middleware-logger": "3.901.0",
18921
18921
  "@aws-sdk/middleware-recursion-detection": "3.901.0",
18922
- "@aws-sdk/middleware-user-agent": "3.906.0",
18922
+ "@aws-sdk/middleware-user-agent": "3.907.0",
18923
18923
  "@aws-sdk/region-config-resolver": "3.901.0",
18924
18924
  "@aws-sdk/types": "3.901.0",
18925
18925
  "@aws-sdk/util-endpoints": "3.901.0",
18926
- "@aws-sdk/util-user-agent-browser": "3.901.0",
18927
- "@aws-sdk/util-user-agent-node": "3.906.0",
18926
+ "@aws-sdk/util-user-agent-browser": "3.907.0",
18927
+ "@aws-sdk/util-user-agent-node": "3.907.0",
18928
18928
  "@smithy/config-resolver": "^4.3.0",
18929
18929
  "@smithy/core": "^3.14.0",
18930
18930
  "@smithy/fetch-http-handler": "^5.3.0",
@@ -26172,7 +26172,7 @@ var init_BytePairEncodingCore = __esm({
26172
26172
  var chatEnabledModels;
26173
26173
  var init_modelsChatEnabled_gen = __esm({
26174
26174
  "node_modules/gpt-tokenizer/esm/modelsChatEnabled.gen.js"() {
26175
- 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"];
26175
+ 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"];
26176
26176
  }
26177
26177
  });
26178
26178
 
@@ -26568,8 +26568,9 @@ var init_GptEncoding = __esm({
26568
26568
  * Returns tokens assuming the 'gpt-3.5-turbo-0301' / 'gpt-4-0314' format.
26569
26569
  * Based on OpenAI's guidelines: https://github.com/openai/openai-python/blob/main/chatml.md
26570
26570
  * Also mentioned in section 6 of this document: https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb
26571
+ * @param encodeOptions Options controlling how special tokens are handled.
26571
26572
  */
26572
- *encodeChatGenerator(chat, model = this.modelName) {
26573
+ *encodeChatGenerator(chat, model = this.modelName, encodeOptions) {
26573
26574
  if (!model) {
26574
26575
  throw new Error("Model name must be provided either during initialization or passed in to the method.");
26575
26576
  }
@@ -26595,12 +26596,12 @@ var init_GptEncoding = __esm({
26595
26596
  if (encodedRoleSeparator.length > 0) {
26596
26597
  yield encodedRoleSeparator;
26597
26598
  }
26598
- yield* this.encodeGenerator(content);
26599
+ yield* this.encodeGenerator(content, encodeOptions);
26599
26600
  yield [chatEndToken];
26600
26601
  yield encodedMessageSeparator;
26601
26602
  }
26602
26603
  yield [chatStartToken];
26603
- yield* this.encodeGenerator("assistant");
26604
+ yield* this.encodeGenerator("assistant", encodeOptions);
26604
26605
  if (encodedRoleSeparator.length > 0) {
26605
26606
  yield encodedRoleSeparator;
26606
26607
  }
@@ -26611,15 +26612,20 @@ var init_GptEncoding = __esm({
26611
26612
  * Returns tokens assuming the 'gpt-3.5-turbo-0301' / 'gpt-4-0314' format.
26612
26613
  * Based on OpenAI's guidelines: https://github.com/openai/openai-python/blob/main/chatml.md
26613
26614
  * Also mentioned in section 6 of this document: https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb
26615
+ * @param encodeOptions Options controlling how special tokens are handled.
26614
26616
  */
26615
- encodeChat(chat, model = this.modelName) {
26616
- return [...this.encodeChatGenerator(chat, model)].flat();
26617
+ encodeChat(chat, model = this.modelName, encodeOptions) {
26618
+ return [...this.encodeChatGenerator(chat, model, encodeOptions)].flat();
26617
26619
  }
26618
26620
  /**
26621
+ * Checks whether the provided input stays within the provided token limit.
26622
+ * @param input The string or chat messages to evaluate.
26623
+ * @param tokenLimit The maximum allowed number of tokens.
26624
+ * @param encodeOptions Options controlling how special tokens are handled.
26619
26625
  * @returns {false | number} false if token limit is exceeded, otherwise the number of tokens
26620
26626
  */
26621
- isWithinTokenLimit(input, tokenLimit) {
26622
- const tokenGenerator = typeof input === "string" ? this.encodeGenerator(input) : this.encodeChatGenerator(input);
26627
+ isWithinTokenLimit(input, tokenLimit, encodeOptions) {
26628
+ const tokenGenerator = typeof input === "string" ? this.encodeGenerator(input, encodeOptions) : this.encodeChatGenerator(input, void 0, encodeOptions);
26623
26629
  let count = 0;
26624
26630
  for (const tokens of tokenGenerator) {
26625
26631
  count += tokens.length;
@@ -26631,6 +26637,8 @@ var init_GptEncoding = __esm({
26631
26637
  }
26632
26638
  /**
26633
26639
  * Counts the number of tokens in the input.
26640
+ * @param input The string or chat messages to evaluate.
26641
+ * @param encodeOptions Options controlling how special tokens are handled.
26634
26642
  * @returns {number} The number of tokens.
26635
26643
  */
26636
26644
  countTokens(input, encodeOptions) {
@@ -26644,7 +26652,7 @@ var init_GptEncoding = __esm({
26644
26652
  }
26645
26653
  return this.bytePairEncodingCoreProcessor.countNative(input, specialTokenConfig.allowedSpecial);
26646
26654
  }
26647
- const tokenGenerator = this.encodeChatGenerator(input);
26655
+ const tokenGenerator = this.encodeChatGenerator(input, void 0, encodeOptions);
26648
26656
  let count = 0;
26649
26657
  for (const tokens of tokenGenerator) {
26650
26658
  count += tokens.length;
@@ -27082,6 +27090,226 @@ var init_tokenCounter = __esm({
27082
27090
  }
27083
27091
  });
27084
27092
 
27093
+ // src/agent/storage/StorageAdapter.js
27094
+ var StorageAdapter;
27095
+ var init_StorageAdapter = __esm({
27096
+ "src/agent/storage/StorageAdapter.js"() {
27097
+ "use strict";
27098
+ StorageAdapter = class {
27099
+ /**
27100
+ * Load conversation history for a session
27101
+ * @param {string} sessionId - Session identifier
27102
+ * @returns {Promise<Array<Object>>} Array of message objects with {role, content, ...}
27103
+ */
27104
+ async loadHistory(sessionId) {
27105
+ throw new Error("StorageAdapter.loadHistory() must be implemented by subclass");
27106
+ }
27107
+ /**
27108
+ * Save a message to storage
27109
+ * @param {string} sessionId - Session identifier
27110
+ * @param {Object} message - Message object { role, content, ... }
27111
+ * @returns {Promise<void>}
27112
+ */
27113
+ async saveMessage(sessionId, message) {
27114
+ throw new Error("StorageAdapter.saveMessage() must be implemented by subclass");
27115
+ }
27116
+ /**
27117
+ * Clear history for a session
27118
+ * @param {string} sessionId - Session identifier
27119
+ * @returns {Promise<void>}
27120
+ */
27121
+ async clearHistory(sessionId) {
27122
+ throw new Error("StorageAdapter.clearHistory() must be implemented by subclass");
27123
+ }
27124
+ /**
27125
+ * Get session metadata (optional)
27126
+ * @param {string} sessionId - Session identifier
27127
+ * @returns {Promise<Object|null>} Session metadata or null
27128
+ */
27129
+ async getSessionMetadata(sessionId) {
27130
+ return null;
27131
+ }
27132
+ /**
27133
+ * Update session activity timestamp (optional)
27134
+ * @param {string} sessionId - Session identifier
27135
+ * @returns {Promise<void>}
27136
+ */
27137
+ async updateSessionActivity(sessionId) {
27138
+ }
27139
+ };
27140
+ }
27141
+ });
27142
+
27143
+ // src/agent/storage/InMemoryStorageAdapter.js
27144
+ var InMemoryStorageAdapter;
27145
+ var init_InMemoryStorageAdapter = __esm({
27146
+ "src/agent/storage/InMemoryStorageAdapter.js"() {
27147
+ "use strict";
27148
+ init_StorageAdapter();
27149
+ InMemoryStorageAdapter = class extends StorageAdapter {
27150
+ constructor() {
27151
+ super();
27152
+ this.sessions = /* @__PURE__ */ new Map();
27153
+ }
27154
+ async loadHistory(sessionId) {
27155
+ const session = this.sessions.get(sessionId);
27156
+ return session ? session.messages : [];
27157
+ }
27158
+ async saveMessage(sessionId, message) {
27159
+ if (!this.sessions.has(sessionId)) {
27160
+ this.sessions.set(sessionId, {
27161
+ messages: [],
27162
+ metadata: {
27163
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
27164
+ lastActivity: (/* @__PURE__ */ new Date()).toISOString()
27165
+ }
27166
+ });
27167
+ }
27168
+ const session = this.sessions.get(sessionId);
27169
+ session.messages.push(message);
27170
+ session.metadata.lastActivity = (/* @__PURE__ */ new Date()).toISOString();
27171
+ }
27172
+ async clearHistory(sessionId) {
27173
+ this.sessions.delete(sessionId);
27174
+ }
27175
+ async getSessionMetadata(sessionId) {
27176
+ const session = this.sessions.get(sessionId);
27177
+ return session ? session.metadata : null;
27178
+ }
27179
+ async updateSessionActivity(sessionId) {
27180
+ const session = this.sessions.get(sessionId);
27181
+ if (session) {
27182
+ session.metadata.lastActivity = (/* @__PURE__ */ new Date()).toISOString();
27183
+ }
27184
+ }
27185
+ };
27186
+ }
27187
+ });
27188
+
27189
+ // src/agent/hooks/HookManager.js
27190
+ var HookManager, HOOK_TYPES;
27191
+ var init_HookManager = __esm({
27192
+ "src/agent/hooks/HookManager.js"() {
27193
+ "use strict";
27194
+ HookManager = class {
27195
+ constructor() {
27196
+ this.hooks = /* @__PURE__ */ new Map();
27197
+ }
27198
+ /**
27199
+ * Register a hook callback
27200
+ * @param {string} hookName - Name of the hook
27201
+ * @param {Function} callback - Callback function
27202
+ * @returns {Function} Unregister function
27203
+ */
27204
+ on(hookName, callback) {
27205
+ if (!this.hooks.has(hookName)) {
27206
+ this.hooks.set(hookName, /* @__PURE__ */ new Set());
27207
+ }
27208
+ this.hooks.get(hookName).add(callback);
27209
+ return () => this.off(hookName, callback);
27210
+ }
27211
+ /**
27212
+ * Register a one-time hook callback
27213
+ * @param {string} hookName - Name of the hook
27214
+ * @param {Function} callback - Callback function
27215
+ * @returns {Function} Unregister function
27216
+ */
27217
+ once(hookName, callback) {
27218
+ const wrappedCallback = async (data2) => {
27219
+ this.off(hookName, wrappedCallback);
27220
+ await callback(data2);
27221
+ };
27222
+ return this.on(hookName, wrappedCallback);
27223
+ }
27224
+ /**
27225
+ * Unregister a hook callback
27226
+ * @param {string} hookName - Name of the hook
27227
+ * @param {Function} callback - Callback function
27228
+ */
27229
+ off(hookName, callback) {
27230
+ const callbacks = this.hooks.get(hookName);
27231
+ if (callbacks) {
27232
+ callbacks.delete(callback);
27233
+ }
27234
+ }
27235
+ /**
27236
+ * Emit a hook event
27237
+ * @param {string} hookName - Name of the hook
27238
+ * @param {any} data - Data to pass to callbacks
27239
+ * @returns {Promise<void>}
27240
+ */
27241
+ async emit(hookName, data2) {
27242
+ const callbacks = this.hooks.get(hookName);
27243
+ if (!callbacks || callbacks.size === 0) return;
27244
+ const promises = Array.from(callbacks).map((callback) => {
27245
+ try {
27246
+ return Promise.resolve(callback(data2));
27247
+ } catch (error2) {
27248
+ return Promise.reject(error2);
27249
+ }
27250
+ });
27251
+ const results = await Promise.allSettled(promises);
27252
+ results.forEach((result, index) => {
27253
+ if (result.status === "rejected") {
27254
+ console.error(`[HookManager] Error in hook "${hookName}" (callback ${index + 1}):`, result.reason);
27255
+ }
27256
+ });
27257
+ }
27258
+ /**
27259
+ * Clear all hooks or hooks for a specific event
27260
+ * @param {string} [hookName] - Optional hook name to clear
27261
+ */
27262
+ clear(hookName) {
27263
+ if (hookName) {
27264
+ this.hooks.delete(hookName);
27265
+ } else {
27266
+ this.hooks.clear();
27267
+ }
27268
+ }
27269
+ /**
27270
+ * Get list of registered hook names
27271
+ * @returns {string[]} Array of hook names
27272
+ */
27273
+ getHookNames() {
27274
+ return Array.from(this.hooks.keys());
27275
+ }
27276
+ /**
27277
+ * Get number of callbacks for a hook
27278
+ * @param {string} hookName - Name of the hook
27279
+ * @returns {number} Number of callbacks
27280
+ */
27281
+ getCallbackCount(hookName) {
27282
+ const callbacks = this.hooks.get(hookName);
27283
+ return callbacks ? callbacks.size : 0;
27284
+ }
27285
+ };
27286
+ HOOK_TYPES = {
27287
+ // Lifecycle hooks
27288
+ AGENT_INITIALIZED: "agent:initialized",
27289
+ AGENT_CLEANUP: "agent:cleanup",
27290
+ // Message hooks
27291
+ MESSAGE_USER: "message:user",
27292
+ MESSAGE_ASSISTANT: "message:assistant",
27293
+ MESSAGE_SYSTEM: "message:system",
27294
+ // Tool execution hooks
27295
+ TOOL_START: "tool:start",
27296
+ TOOL_END: "tool:end",
27297
+ TOOL_ERROR: "tool:error",
27298
+ // AI streaming hooks
27299
+ AI_STREAM_START: "ai:stream:start",
27300
+ AI_STREAM_DELTA: "ai:stream:delta",
27301
+ AI_STREAM_END: "ai:stream:end",
27302
+ // Storage hooks
27303
+ STORAGE_LOAD: "storage:load",
27304
+ STORAGE_SAVE: "storage:save",
27305
+ STORAGE_CLEAR: "storage:clear",
27306
+ // Iteration hooks
27307
+ ITERATION_START: "iteration:start",
27308
+ ITERATION_END: "iteration:end"
27309
+ };
27310
+ }
27311
+ });
27312
+
27085
27313
  // src/directory-resolver.js
27086
27314
  async function getPackageBinDir() {
27087
27315
  const debug = process.env.DEBUG === "1" || process.env.VERBOSE === "1";
@@ -41524,6 +41752,23 @@ var init_probeTool = __esm({
41524
41752
  }
41525
41753
  });
41526
41754
 
41755
+ // src/agent/storage/index.js
41756
+ var init_storage = __esm({
41757
+ "src/agent/storage/index.js"() {
41758
+ "use strict";
41759
+ init_StorageAdapter();
41760
+ init_InMemoryStorageAdapter();
41761
+ }
41762
+ });
41763
+
41764
+ // src/agent/hooks/index.js
41765
+ var init_hooks = __esm({
41766
+ "src/agent/hooks/index.js"() {
41767
+ "use strict";
41768
+ init_HookManager();
41769
+ }
41770
+ });
41771
+
41527
41772
  // src/index.js
41528
41773
  var init_index = __esm({
41529
41774
  "src/index.js"() {
@@ -41543,6 +41788,8 @@ var init_index = __esm({
41543
41788
  init_ProbeAgent();
41544
41789
  init_simpleTelemetry();
41545
41790
  init_probeTool();
41791
+ init_storage();
41792
+ init_hooks();
41546
41793
  }
41547
41794
  });
41548
41795
 
@@ -53507,7 +53754,6 @@ var init_parser2 = __esm({
53507
53754
  this.linkStyleStatement = this.RULE("linkStyleStatement", () => {
53508
53755
  this.CONSUME(LinkStyleKeyword);
53509
53756
  this.SUBRULE(this.linkStyleIndexList);
53510
- this.OPTION1(() => this.CONSUME1(Newline));
53511
53757
  this.SUBRULE(this.linkStylePairs);
53512
53758
  this.OPTION2(() => this.CONSUME2(Newline));
53513
53759
  });
@@ -53971,7 +54217,7 @@ var init_semantics = __esm({
53971
54217
  }
53972
54218
  const fnTok = ch.fn?.[0];
53973
54219
  if (!fnTok) {
53974
- this.ctx.errors.push({ line: modeTok2?.startLine ?? 1, column: modeTok2?.startColumn ?? 1, severity: "error", code: "FL-CLICK-CALL-NAME-MISSING", message: "'click \u2026 call' requires a function name.", hint: 'Example: click A call doThing() "Tooltip"' });
54220
+ this.ctx.errors.push({ line: modeTok2?.startLine ?? 1, column: modeTok2?.startColumn ?? 1, severity: "error", code: "FL-CLICK-CALL-NAME-MISSING", message: "'click \u2026 call' requires a function name.", hint: "Example: click A call doThing()" });
53975
54221
  }
53976
54222
  const tipTok = ch.tooltip?.[0];
53977
54223
  if (tipTok) {
@@ -54028,7 +54274,7 @@ var init_semantics = __esm({
54028
54274
  severity: "error",
54029
54275
  code: "FL-CLICK-CALL-NAME-MISSING",
54030
54276
  message: "'click \u2026 call' requires a function name.",
54031
- hint: 'Example: click A call doThing() "Tooltip"'
54277
+ hint: "Example: click A call doThing()"
54032
54278
  });
54033
54279
  }
54034
54280
  return;
@@ -54109,6 +54355,8 @@ var init_semantics = __esm({
54109
54355
  const linksHere = Array.isArray(ctx.link) ? ctx.link.length : 0;
54110
54356
  if (linksHere > 0)
54111
54357
  this.edgeCount += linksHere;
54358
+ if (ctx.link)
54359
+ ctx.link.forEach((ln) => this.visit(ln));
54112
54360
  }
54113
54361
  // Edge attribute object statements must target a known edge id
54114
54362
  // Edge attribute statements are parsed as nodeStatements with a typed attrObject and no links.
@@ -54168,7 +54416,7 @@ var init_semantics = __esm({
54168
54416
  severity: "error",
54169
54417
  code: "FL-TYPED-SHAPE-UNKNOWN",
54170
54418
  message: `Unknown shape '${v3}' in '@{ shape: \u2026 }'.`,
54171
- hint: "Use one of: rect, round, stadium, subroutine, circle, cylinder, diamond, trapezoid, parallelogram, hexagon, lean-l, lean-r, icon, image"
54419
+ hint: 'Use one of: rect, rounded, stadium, subroutine, circle, cylinder, diamond, trapezoid, parallelogram, hexagon, "lean-l", "lean-r", icon, image'
54172
54420
  });
54173
54421
  } else {
54174
54422
  const supportedByCli = /* @__PURE__ */ new Set(["rect", "round", "rounded", "diamond", "circle", "cylinder", "stadium", "subroutine", "lean-l", "lean-r"]);
@@ -54370,8 +54618,8 @@ var init_semantics = __esm({
54370
54618
  column: t3.startColumn ?? 1,
54371
54619
  severity: "error",
54372
54620
  code: "FL-LABEL-PARENS-UNQUOTED",
54373
- message: "Parentheses inside an unquoted label are not supported by Mermaid. Wrap the label in quotes.",
54374
- hint: 'Example: A["Calls func(arg)"]'
54621
+ message: "Parentheses inside an unquoted label are not supported by Mermaid.",
54622
+ hint: 'Wrap the label in quotes, e.g., A["Mark (X)"] \u2014 or replace ( and ) with HTML entities: &#40; and &#41;'
54375
54623
  });
54376
54624
  }
54377
54625
  }
@@ -54419,6 +54667,29 @@ var init_semantics = __esm({
54419
54667
  }
54420
54668
  }
54421
54669
  }
54670
+ // Validate link specifics that Mermaid CLI enforces but our grammar may parse loosely
54671
+ link(ctx) {
54672
+ const inline = ctx.linkTextInline?.[0];
54673
+ if (inline) {
54674
+ const ch = inline.children || {};
54675
+ const parts = [].concat(ch.Identifier || []).concat(ch.Text || []).concat(ch.NumberLiteral || []).concat(ch.Pipe || []);
54676
+ if (parts.length) {
54677
+ const raw = parts.map((t3) => String(t3.image || "")).join("").trim();
54678
+ if (raw === "x" || raw === "o") {
54679
+ const p3 = parts[0];
54680
+ this.ctx.errors.push({
54681
+ line: p3.startLine ?? 1,
54682
+ column: p3.startColumn ?? 1,
54683
+ severity: "error",
54684
+ code: "FL-LINK-UNSUPPORTED-MARKER",
54685
+ message: `Unsupported one-sided link marker '${raw}'. Use symmetric '${raw}--${raw}' or a plain arrow with a label.`,
54686
+ hint: raw === "x" ? "Example: A x--x B (or) A --> B and label it: A --|Skipped|--> B" : "Example: A o--o B (or) A --> B",
54687
+ length: p3.image?.length ?? 1
54688
+ });
54689
+ }
54690
+ }
54691
+ }
54692
+ }
54422
54693
  checkBackticksInContent(contentNodes) {
54423
54694
  if (!contentNodes)
54424
54695
  return;
@@ -54770,6 +55041,31 @@ function mapFlowchartParserError(err, text) {
54770
55041
  }
54771
55042
  }
54772
55043
  }
55044
+ if (isInRule(err, "linkStylePairs") && tokType === "Newline") {
55045
+ const nextLine = Math.min(allLines.length, line + 1);
55046
+ const nxt = allLines[nextLine - 1] || "";
55047
+ const first2 = (nxt.match(/\S/) || { index: 0 }).index || 0;
55048
+ return {
55049
+ line: nextLine,
55050
+ column: Math.max(1, first2 + 1),
55051
+ severity: "error",
55052
+ code: "FL-LINKSTYLE-MULTILINE",
55053
+ message: "'linkStyle' styles must be on the same line as the indices.",
55054
+ hint: "Example: linkStyle 0,1 stroke:#f00,stroke-width:2px",
55055
+ length: 1
55056
+ };
55057
+ }
55058
+ if ((isInRule(err, "linkStyleIndexList") || isInRule(err, "linkStyleStatement")) && tokType === "Colon") {
55059
+ return {
55060
+ line,
55061
+ column,
55062
+ severity: "error",
55063
+ code: "FL-LINKSTYLE-RANGE-NOT-SUPPORTED",
55064
+ message: "Ranges in 'linkStyle' indices are not supported. Use comma-separated indices.",
55065
+ hint: "Example: linkStyle 0,1 stroke:#f00,stroke-width:2px",
55066
+ length: len
55067
+ };
55068
+ }
54773
55069
  if (tokType === "QuotedString") {
54774
55070
  const context = err?.context;
54775
55071
  const inLinkRule = context?.ruleStack?.includes("linkTextInline") || context?.ruleStack?.includes("link") || false;
@@ -54816,6 +55112,17 @@ function mapFlowchartParserError(err, text) {
54816
55112
  }
54817
55113
  if (isInRule(err, "nodeShape") && err.name === "MismatchedTokenException") {
54818
55114
  if (expecting(err, "SquareClose")) {
55115
+ if (tokType === "RoundOpen" || tokType === "RoundClose") {
55116
+ return {
55117
+ line,
55118
+ column,
55119
+ severity: "error",
55120
+ code: "FL-LABEL-PARENS-UNQUOTED",
55121
+ message: "Parentheses inside an unquoted label are not supported by Mermaid.",
55122
+ hint: 'Wrap the label in quotes, e.g., A["Mark (X)"] \u2014 or replace ( and ) with HTML entities: &#40; and &#41;.',
55123
+ length: len
55124
+ };
55125
+ }
54819
55126
  if (tokType === "QuotedString") {
54820
55127
  return {
54821
55128
  line,
@@ -55311,6 +55618,32 @@ ${br.example}`,
55311
55618
  break;
55312
55619
  }
55313
55620
  }
55621
+ if (blk.label === "box" && openIdx !== -1) {
55622
+ let endIdx = -1;
55623
+ for (let i3 = openIdx + 1; i3 < lines2.length; i3++) {
55624
+ const raw = lines2[i3] || "";
55625
+ const ind = raw.match(/^(\s*)/)?.[1] || "";
55626
+ if (/^\s*end\s*$/.test(raw) && ind.length <= openIndent.length) {
55627
+ endIdx = i3;
55628
+ break;
55629
+ }
55630
+ }
55631
+ if (endIdx !== -1) {
55632
+ const body = lines2.slice(openIdx + 1, endIdx).map((s3) => (s3 || "").trim());
55633
+ const hasMsgWithActivation = body.some((s3) => /->/.test(s3) && /[+-]/.test(s3));
55634
+ if (hasMsgWithActivation) {
55635
+ return {
55636
+ line: openIdx + 1,
55637
+ column: 1,
55638
+ severity: "error",
55639
+ code: "SE-BOX-EMPTY",
55640
+ message: "Box block has no participant/actor declarations. Use 'rect' to group messages visually.",
55641
+ hint: "Replace 'box' with 'rect' if you want to group messages:\nrect rgb(240, 240, 255)\n A->>B: Message\n Note over A: Info\nend",
55642
+ length: 3
55643
+ };
55644
+ }
55645
+ }
55646
+ }
55314
55647
  let caretLine = line;
55315
55648
  if (openIdx !== -1) {
55316
55649
  caretLine = lines2.length;
@@ -56650,7 +56983,7 @@ var init_validate3 = __esm({
56650
56983
  function tokenize4(text) {
56651
56984
  return ClassLexer.tokenize(text);
56652
56985
  }
56653
- var Identifier3, NumberLiteral4, ClassDiagramKeyword, DirectionKw, Direction2, ClassKw, AsKw, NoteKw, ForKw, RelCompToAgg, RelAggToComp, RelCompBoth, RelAggBoth, LollipopLeft, LollipopRight, RelExtends, RelComposition, RelAggregation, RelDependency, RelRealization, RelAssociation, RelDependencyLeft, RelRealizationLeft, RelExtendsRight, InvalidRelArrow, LCurly, RCurly, LParen2, RParen2, Colon4, Comma3, Visibility, LTlt, GTgt, GenericAngle, QuotedString4, BacktickName, SquareOpen2, SquareClose2, Comment4, WhiteSpace4, Newline4, allTokens4, ClassLexer;
56986
+ var Identifier3, NumberLiteral4, ClassDiagramKeyword, DirectionKw, Direction2, TitleKw, NamespaceKw, ClassKw, InterfaceKw, AsKw, NoteKw, ForKw, RelCompToAgg, RelAggToComp, RelCompBoth, RelAggBoth, LollipopLeft, LollipopRight, RelExtends, RelComposition, RelAggregation, RelDependency, RelRealization, RelAssociation, RelDependencyLeft, RelRealizationLeft, RelExtendsRight, InvalidRelArrow, LCurly, RCurly, LParen2, RParen2, Colon4, Comma3, Visibility, LTlt, GTgt, GenericAngle, QuotedString4, BacktickName, SquareOpen2, SquareClose2, Comment4, WhiteSpace4, Newline4, allTokens4, ClassLexer;
56654
56987
  var init_lexer5 = __esm({
56655
56988
  "node_modules/@probelabs/maid/out/diagrams/class/lexer.js"() {
56656
56989
  init_api5();
@@ -56659,7 +56992,10 @@ var init_lexer5 = __esm({
56659
56992
  ClassDiagramKeyword = createToken({ name: "ClassDiagramKeyword", pattern: /classDiagram/, longer_alt: Identifier3 });
56660
56993
  DirectionKw = createToken({ name: "DirectionKw", pattern: /direction/, longer_alt: Identifier3 });
56661
56994
  Direction2 = createToken({ name: "Direction", pattern: /LR|RL|TB|BT|TD/, longer_alt: Identifier3 });
56995
+ TitleKw = createToken({ name: "TitleKw", pattern: /title/, longer_alt: Identifier3 });
56996
+ NamespaceKw = createToken({ name: "NamespaceKw", pattern: /namespace/, longer_alt: Identifier3 });
56662
56997
  ClassKw = createToken({ name: "ClassKw", pattern: /class/, longer_alt: Identifier3 });
56998
+ InterfaceKw = createToken({ name: "InterfaceKw", pattern: /interface\b/, longer_alt: Identifier3 });
56663
56999
  AsKw = createToken({ name: "AsKw", pattern: /as/, longer_alt: Identifier3 });
56664
57000
  NoteKw = createToken({ name: "NoteKw", pattern: /note/, longer_alt: Identifier3 });
56665
57001
  ForKw = createToken({ name: "ForKw", pattern: /for/, longer_alt: Identifier3 });
@@ -56702,6 +57038,9 @@ var init_lexer5 = __esm({
56702
57038
  // Keywords
56703
57039
  ClassDiagramKeyword,
56704
57040
  DirectionKw,
57041
+ TitleKw,
57042
+ NamespaceKw,
57043
+ InterfaceKw,
56705
57044
  ClassKw,
56706
57045
  AsKw,
56707
57046
  NoteKw,
@@ -56770,8 +57109,11 @@ var init_parser5 = __esm({
56770
57109
  });
56771
57110
  this.statement = this.RULE("statement", () => {
56772
57111
  this.OR([
57112
+ { ALT: () => this.SUBRULE(this.titleStmt) },
56773
57113
  { ALT: () => this.SUBRULE(this.directionStmt) },
57114
+ { ALT: () => this.SUBRULE(this.namespaceStmt) },
56774
57115
  { ALT: () => this.SUBRULE(this.classLine) },
57116
+ { ALT: () => this.SUBRULE(this.interfaceLine) },
56775
57117
  { ALT: () => this.SUBRULE(this.relationStmt) },
56776
57118
  { ALT: () => this.SUBRULE(this.noteStmt) },
56777
57119
  { ALT: () => this.SUBRULE(this.memberAssignStmt) },
@@ -56783,6 +57125,43 @@ var init_parser5 = __esm({
56783
57125
  this.CONSUME(Direction2);
56784
57126
  this.OPTION(() => this.CONSUME(Newline4));
56785
57127
  });
57128
+ this.titleStmt = this.RULE("titleStmt", () => {
57129
+ this.CONSUME(TitleKw);
57130
+ this.OR([
57131
+ { ALT: () => this.CONSUME(QuotedString4) },
57132
+ {
57133
+ ALT: () => {
57134
+ this.AT_LEAST_ONE(() => {
57135
+ this.OR2([
57136
+ { ALT: () => this.CONSUME(Identifier3) },
57137
+ { ALT: () => this.CONSUME(NumberLiteral4) }
57138
+ ]);
57139
+ });
57140
+ }
57141
+ }
57142
+ ]);
57143
+ this.OPTION(() => this.CONSUME(Newline4));
57144
+ });
57145
+ this.namespaceStmt = this.RULE("namespaceStmt", () => {
57146
+ this.CONSUME(NamespaceKw);
57147
+ this.OR([
57148
+ { ALT: () => this.CONSUME(QuotedString4) },
57149
+ { ALT: () => this.CONSUME(Identifier3) }
57150
+ ]);
57151
+ this.CONSUME(LCurly);
57152
+ this.MANY(() => {
57153
+ this.OR2([
57154
+ { ALT: () => this.CONSUME(Newline4) },
57155
+ { ALT: () => this.SUBRULE(this.classLine) },
57156
+ { ALT: () => this.SUBRULE(this.interfaceLine) },
57157
+ { ALT: () => this.SUBRULE(this.relationStmt) },
57158
+ { ALT: () => this.SUBRULE(this.noteStmt) },
57159
+ { ALT: () => this.SUBRULE(this.memberAssignStmt) }
57160
+ ]);
57161
+ });
57162
+ this.CONSUME(RCurly);
57163
+ this.OPTION(() => this.CONSUME2(Newline4));
57164
+ });
56786
57165
  this.classLine = this.RULE("classLine", () => {
56787
57166
  this.CONSUME(ClassKw);
56788
57167
  this.SUBRULE(this.classRef);
@@ -56821,6 +57200,44 @@ var init_parser5 = __esm({
56821
57200
  }
56822
57201
  ]);
56823
57202
  });
57203
+ this.interfaceLine = this.RULE("interfaceLine", () => {
57204
+ this.CONSUME(InterfaceKw);
57205
+ this.SUBRULE(this.classRef);
57206
+ this.OR([
57207
+ {
57208
+ ALT: () => {
57209
+ this.CONSUME(LCurly);
57210
+ this.MANY(() => {
57211
+ this.OR2([
57212
+ { ALT: () => this.CONSUME3(Newline4) },
57213
+ { ALT: () => this.SUBRULE(this.memberLineStmt) }
57214
+ ]);
57215
+ });
57216
+ this.CONSUME(RCurly);
57217
+ this.OPTION(() => this.CONSUME(Newline4));
57218
+ }
57219
+ },
57220
+ {
57221
+ ALT: () => {
57222
+ this.OPTION1(() => {
57223
+ this.CONSUME(SquareOpen2);
57224
+ this.CONSUME(QuotedString4);
57225
+ this.CONSUME(SquareClose2);
57226
+ });
57227
+ this.OPTION2(() => {
57228
+ this.CONSUME(LTlt);
57229
+ this.CONSUME2(Identifier3);
57230
+ this.CONSUME(GTgt);
57231
+ });
57232
+ this.OPTION3(() => {
57233
+ this.CONSUME(AsKw);
57234
+ this.CONSUME3(Identifier3);
57235
+ });
57236
+ this.OPTION4(() => this.CONSUME2(Newline4));
57237
+ }
57238
+ }
57239
+ ]);
57240
+ });
56824
57241
  this.memberAssignStmt = this.RULE("memberAssignStmt", () => {
56825
57242
  this.SUBRULE(this.classRef);
56826
57243
  this.CONSUME(Colon4);
@@ -56990,6 +57407,31 @@ function validateClass(text, _options = {}) {
56990
57407
  length: b3.image?.length ?? 1
56991
57408
  });
56992
57409
  }
57410
+ if (a3.tokenType === NamespaceKw && b3.tokenType === QuotedString4) {
57411
+ errs.push({
57412
+ line: b3.startLine ?? 1,
57413
+ column: b3.startColumn ?? 1,
57414
+ severity: "error",
57415
+ code: "CL-NAMESPACE-NAME-QUOTED",
57416
+ message: "Quoted namespace names are not supported by mermaid.js. Use an unquoted identifier.",
57417
+ hint: 'Change: namespace "ProbeAgent Core" { ... } \u2192 namespace ProbeAgentCore { ... }',
57418
+ length: b3.image?.length ?? 1
57419
+ });
57420
+ }
57421
+ if (a3.tokenType === InterfaceKw) {
57422
+ const prevToken = i3 > 0 ? tokList[i3 - 1] : null;
57423
+ if (!prevToken || prevToken.tokenType !== LTlt) {
57424
+ errs.push({
57425
+ line: a3.startLine ?? 1,
57426
+ column: a3.startColumn ?? 1,
57427
+ severity: "error",
57428
+ code: "CL-INTERFACE-KEYWORD-UNSUPPORTED",
57429
+ message: 'The "interface" keyword is not supported by mermaid.js. Use the <<interface>> annotation instead.',
57430
+ hint: 'Auto-fix converts to "class". Then manually add: <<interface>> ClassName after the class definition',
57431
+ length: a3.image?.length ?? 9
57432
+ });
57433
+ }
57434
+ }
56993
57435
  }
56994
57436
  for (const tk of tokList) {
56995
57437
  if (tk.tokenType === InvalidRelArrow) {
@@ -57046,10 +57488,13 @@ function validateClass(text, _options = {}) {
57046
57488
  const has2 = (code, line) => (prev || []).some((e3) => e3.code === code && e3.line === line && e3.severity === "error");
57047
57489
  const lines = src.split(/\r?\n/);
57048
57490
  const classDeclOpen = [];
57491
+ const namespaceDeclOpen = [];
57049
57492
  for (let i3 = 0; i3 < lines.length; i3++) {
57050
57493
  const raw = lines[i3] || "";
57051
57494
  if (/^\s*class\b.*\{\s*$/.test(raw))
57052
57495
  classDeclOpen.push(i3 + 1);
57496
+ if (/^\s*namespace\b.*\{\s*$/.test(raw))
57497
+ namespaceDeclOpen.push(i3 + 1);
57053
57498
  }
57054
57499
  if (classDeclOpen.length > 0) {
57055
57500
  const hasClose = lines.some((l3) => /\}/.test(l3));
@@ -57058,6 +57503,13 @@ function validateClass(text, _options = {}) {
57058
57503
  errors.push({ line: Math.max(1, lines.length), column: 1, severity: "error", code: "CL-BLOCK-MISSING-RBRACE", message: "Missing '}' to close class block.", hint: "Close the block: class Foo { ... }" });
57059
57504
  }
57060
57505
  }
57506
+ if (namespaceDeclOpen.length > 0) {
57507
+ const hasClose = lines.some((l3) => /\}/.test(l3));
57508
+ if (!hasClose && !has2("CL-NAMESPACE-MISSING-RBRACE", Math.max(1, lines.length))) {
57509
+ const last2 = namespaceDeclOpen[namespaceDeclOpen.length - 1];
57510
+ errors.push({ line: Math.max(1, lines.length), column: 1, severity: "error", code: "CL-NAMESPACE-MISSING-RBRACE", message: "Missing '}' to close namespace block.", hint: 'Close the block: namespace "Name" { ... }' });
57511
+ }
57512
+ }
57061
57513
  return errors;
57062
57514
  }
57063
57515
  });
@@ -57712,6 +58164,10 @@ function computeFixes(text, errors, level = "safe") {
57712
58164
  edits.push(replaceRange(text, at(e3), e3.length ?? 2, "-->"));
57713
58165
  continue;
57714
58166
  }
58167
+ if (is("FL-LINK-UNSUPPORTED-MARKER", e3)) {
58168
+ edits.push(replaceRange(text, at(e3), e3.length ?? 1, ""));
58169
+ continue;
58170
+ }
57715
58171
  if (is("FL-EDGE-LABEL-QUOTED", e3)) {
57716
58172
  const lineText = lineTextAt(text, e3.line);
57717
58173
  const col = Math.max(0, e3.column - 1);
@@ -57784,6 +58240,29 @@ function computeFixes(text, errors, level = "safe") {
57784
58240
  }
57785
58241
  continue;
57786
58242
  }
58243
+ if (is("CL-NAMESPACE-NAME-QUOTED", e3)) {
58244
+ const lineText = lineTextAt(text, e3.line);
58245
+ const nsIdx = lineText.indexOf("namespace");
58246
+ const startSearch = nsIdx >= 0 ? nsIdx + 9 : 0;
58247
+ const q1 = lineText.indexOf('"', startSearch);
58248
+ if (q1 !== -1) {
58249
+ const q22 = lineText.indexOf('"', q1 + 1);
58250
+ if (q22 > q1) {
58251
+ const namespaceName = lineText.slice(q1 + 1, q22);
58252
+ const validIdentifier = namespaceName.replace(/[^A-Za-z0-9_]/g, "");
58253
+ edits.push(replaceRange(text, { line: e3.line, column: q1 + 1 }, q22 - q1 + 1, validIdentifier));
58254
+ }
58255
+ }
58256
+ continue;
58257
+ }
58258
+ if (is("CL-INTERFACE-KEYWORD-UNSUPPORTED", e3)) {
58259
+ const lineText = lineTextAt(text, e3.line);
58260
+ const ifIdx = lineText.indexOf("interface");
58261
+ if (ifIdx !== -1) {
58262
+ edits.push(replaceRange(text, { line: e3.line, column: ifIdx + 1 }, 9, "class"));
58263
+ }
58264
+ continue;
58265
+ }
57787
58266
  if (is("FL-LABEL-ESCAPED-QUOTE", e3)) {
57788
58267
  const lineText = lineTextAt(text, e3.line);
57789
58268
  const caret0 = Math.max(0, e3.column - 1);
@@ -57931,6 +58410,42 @@ function computeFixes(text, errors, level = "safe") {
57931
58410
  const msg = e3.message || "";
57932
58411
  const lineText = lineTextAt(text, e3.line);
57933
58412
  const caret0 = Math.max(0, e3.column - 1);
58413
+ {
58414
+ const openIdx = lineText.indexOf("([");
58415
+ if (openIdx !== -1) {
58416
+ const badClose = lineText.indexOf("})", openIdx + 2);
58417
+ if (badClose !== -1) {
58418
+ edits.push({ start: { line: e3.line, column: badClose + 1 }, end: { line: e3.line, column: badClose + 2 }, newText: "]" });
58419
+ patchedLines.add(e3.line);
58420
+ continue;
58421
+ }
58422
+ }
58423
+ }
58424
+ {
58425
+ const openIdx = lineText.indexOf("[(");
58426
+ if (openIdx !== -1) {
58427
+ const closePair = lineText.indexOf("))", openIdx + 2);
58428
+ if (closePair !== -1) {
58429
+ edits.push({ start: { line: e3.line, column: closePair + 2 }, end: { line: e3.line, column: closePair + 3 }, newText: "]" });
58430
+ patchedLines.add(e3.line);
58431
+ continue;
58432
+ }
58433
+ }
58434
+ }
58435
+ {
58436
+ const openPair = lineText.indexOf("([");
58437
+ if (openPair !== -1) {
58438
+ const badClose = lineText.indexOf("})", openPair + 2);
58439
+ if (badClose !== -1) {
58440
+ edits.push({ start: { line: e3.line, column: badClose + 1 }, end: { line: e3.line, column: badClose + 2 }, newText: "]" });
58441
+ continue;
58442
+ }
58443
+ }
58444
+ }
58445
+ if (/\(\[/.test(lineText) && lineText.indexOf("})", Math.max(0, caret0 - 1)) !== -1) {
58446
+ edits.push(replaceRange(text, at(e3), e3.length ?? 1, "]"));
58447
+ continue;
58448
+ }
57934
58449
  if (msg.includes("opened '('") && msg.includes("closed with ']'")) {
57935
58450
  const openIdx = lineText.lastIndexOf("(", caret0);
57936
58451
  if (openIdx !== -1) {
@@ -58003,7 +58518,36 @@ function computeFixes(text, errors, level = "safe") {
58003
58518
  const caret0 = Math.max(0, e3.column - 1);
58004
58519
  const msg = e3.message || "";
58005
58520
  const bracketMatch = msg.match(/Unclosed '(.+?)'/);
58006
- const expectedOpener = bracketMatch ? bracketMatch[1] : null;
58521
+ const expectedOpener = bracketMatch ? (bracketMatch[1] || "").trim() : null;
58522
+ if (expectedOpener === "((") {
58523
+ if (level === "all") {
58524
+ const openIdx = lineText.lastIndexOf("((", caret0);
58525
+ if (openIdx !== -1) {
58526
+ const contentStart = openIdx + 2;
58527
+ const picks = [];
58528
+ const pushIdx2 = (i3) => {
58529
+ if (i3 >= 0)
58530
+ picks.push(i3);
58531
+ };
58532
+ pushIdx2(lineText.indexOf("-", contentStart));
58533
+ pushIdx2(lineText.indexOf("=", contentStart));
58534
+ pushIdx2(lineText.indexOf(".", contentStart));
58535
+ pushIdx2(lineText.indexOf("|", contentStart));
58536
+ let insertIdx = picks.length ? Math.min(...picks) : lineText.length;
58537
+ const before = lineText.slice(0, openIdx);
58538
+ const m3 = before.match(/([A-Za-z0-9_]+)\s*$/);
58539
+ const inferred = m3 ? m3[1] : "";
58540
+ if (inferred) {
58541
+ edits.push({ start: { line: e3.line, column: contentStart + 1 }, end: { line: e3.line, column: insertIdx + 1 }, newText: inferred + "))" });
58542
+ patchedLines.add(e3.line);
58543
+ continue;
58544
+ }
58545
+ patchedLines.add(e3.line);
58546
+ continue;
58547
+ }
58548
+ }
58549
+ continue;
58550
+ }
58007
58551
  const bracketMap = {
58008
58552
  "[": "]",
58009
58553
  "{": "}",
@@ -58089,6 +58633,14 @@ function computeFixes(text, errors, level = "safe") {
58089
58633
  patchedLines.add(e3.line);
58090
58634
  continue;
58091
58635
  }
58636
+ if (innerSeg.includes("(") || innerSeg.includes(")")) {
58637
+ const replaced = innerSeg.replace(/\(/g, "&#40;").replace(/\)/g, "&#41;");
58638
+ if (replaced !== innerSeg) {
58639
+ edits.push({ start: { line: e3.line, column: opened.idx + opened.len + 1 }, end: { line: e3.line, column: closerIdx + 1 }, newText: replaced });
58640
+ patchedLines.add(e3.line);
58641
+ continue;
58642
+ }
58643
+ }
58092
58644
  }
58093
58645
  }
58094
58646
  if (patchedLines.has(e3.line)) {
@@ -58097,9 +58649,35 @@ function computeFixes(text, errors, level = "safe") {
58097
58649
  let closer = "]";
58098
58650
  if (opened)
58099
58651
  closer = opened.close;
58100
- const avail = lineText.slice(caret0);
58101
- const replaceLen = Math.min(closer.length, Math.max(1, avail.length));
58102
- edits.push({ start: { line: e3.line, column: caret0 + 1 }, end: { line: e3.line, column: caret0 + 1 + replaceLen }, newText: closer });
58652
+ if (closer === "]") {
58653
+ const openIdxSq = lineText.lastIndexOf("[", caret0);
58654
+ if (openIdxSq !== -1) {
58655
+ const picks = [];
58656
+ const pushIdx2 = (i3) => {
58657
+ if (i3 >= 0)
58658
+ picks.push(i3);
58659
+ };
58660
+ pushIdx2(lineText.indexOf("-", openIdxSq + 1));
58661
+ pushIdx2(lineText.indexOf("=", openIdxSq + 1));
58662
+ pushIdx2(lineText.indexOf(".", openIdxSq + 1));
58663
+ pushIdx2(lineText.indexOf("|", openIdxSq + 1));
58664
+ let ins = picks.length ? Math.min(...picks) : lineText.length;
58665
+ let tl = ins - 1;
58666
+ while (tl >= 0 && /\s/.test(lineText[tl]))
58667
+ tl--;
58668
+ const startCol2 = tl + 1 + 1;
58669
+ const endCol2 = ins + 1;
58670
+ edits.push({ start: { line: e3.line, column: startCol2 }, end: { line: e3.line, column: endCol2 }, newText: closer });
58671
+ } else {
58672
+ const avail = lineText.slice(caret0);
58673
+ const replaceLen = Math.min(closer.length, Math.max(1, avail.length));
58674
+ edits.push({ start: { line: e3.line, column: caret0 + 1 }, end: { line: e3.line, column: caret0 + 1 + replaceLen }, newText: closer });
58675
+ }
58676
+ } else {
58677
+ const avail = lineText.slice(caret0);
58678
+ const replaceLen = Math.min(closer.length, Math.max(1, avail.length));
58679
+ edits.push({ start: { line: e3.line, column: caret0 + 1 }, end: { line: e3.line, column: caret0 + 1 + replaceLen }, newText: closer });
58680
+ }
58103
58681
  }
58104
58682
  continue;
58105
58683
  }
@@ -58231,9 +58809,11 @@ function computeFixes(text, errors, level = "safe") {
58231
58809
  if (core.length >= 2 && isSlashPair(left, right)) {
58232
58810
  break;
58233
58811
  }
58234
- const newInner = '"' + inner + '"';
58235
- edits.push({ start: { line: e3.line, column: contentStart + 1 }, end: { line: e3.line, column: closeIdx + 1 }, newText: newInner });
58236
- patchedLines.add(e3.line);
58812
+ const replaced = inner.replace(/\(/g, "&#40;").replace(/\)/g, "&#41;");
58813
+ if (replaced !== inner) {
58814
+ edits.push({ start: { line: e3.line, column: contentStart + 1 }, end: { line: e3.line, column: closeIdx + 1 }, newText: replaced });
58815
+ patchedLines.add(e3.line);
58816
+ }
58237
58817
  break;
58238
58818
  }
58239
58819
  searchStart = openIdx + 1;
@@ -58390,14 +58970,33 @@ function computeFixes(text, errors, level = "safe") {
58390
58970
  continue;
58391
58971
  }
58392
58972
  if (is("SE-BOX-EMPTY", e3)) {
58393
- const lines = text.split(/\r?\n/);
58394
- const boxIdx = Math.max(0, e3.line - 1);
58395
- const boxLine = lines[boxIdx] || "";
58396
- const labelMatch = /^\s*box\s+(.+)$/.exec(boxLine);
58397
- if (labelMatch) {
58398
- const indent = boxLine.match(/^\s*/)?.[0] || "";
58399
- const newLine = `${indent}rect rgb(240, 240, 255)`;
58400
- edits.push({ start: { line: e3.line, column: 1 }, end: { line: e3.line, column: boxLine.length + 1 }, newText: newLine });
58973
+ if (level === "all") {
58974
+ const lines = text.split(/\r?\n/);
58975
+ const boxIdx = Math.max(0, e3.line - 1);
58976
+ const boxLine = lines[boxIdx] || "";
58977
+ const openIndent = (boxLine.match(/^(\s*)/)?.[1] || "").length;
58978
+ let endIdx = -1;
58979
+ for (let i3 = boxIdx + 1; i3 < lines.length; i3++) {
58980
+ const raw = lines[i3] || "";
58981
+ const ind = (raw.match(/^(\s*)/)?.[1] || "").length;
58982
+ if (/^\s*end\s*$/.test(raw) && ind <= openIndent) {
58983
+ endIdx = i3;
58984
+ break;
58985
+ }
58986
+ }
58987
+ let hasMsgWithAct = false;
58988
+ if (endIdx !== -1) {
58989
+ const body = lines.slice(boxIdx + 1, endIdx).map((s3) => (s3 || "").trim());
58990
+ hasMsgWithAct = body.some((s3) => /->/.test(s3) && /[+-]/.test(s3));
58991
+ }
58992
+ if (!hasMsgWithAct) {
58993
+ const labelMatch = /^\s*box\s+(.+)$/.exec(boxLine);
58994
+ if (labelMatch) {
58995
+ const indent = boxLine.match(/^\s*/)?.[0] || "";
58996
+ const newLine = `${indent}rect rgb(240, 240, 255)`;
58997
+ edits.push({ start: { line: e3.line, column: 1 }, end: { line: e3.line, column: boxLine.length + 1 }, newText: newLine });
58998
+ }
58999
+ }
58401
59000
  }
58402
59001
  continue;
58403
59002
  }
@@ -58673,6 +59272,41 @@ ${indent}${tail}` });
58673
59272
  }
58674
59273
  }
58675
59274
  edits.push(insertAt(text, { line: insIdx + 1, column: 1 }, `${openIndent}}
59275
+ `));
59276
+ continue;
59277
+ }
59278
+ if (is("CL-NAMESPACE-MISSING-RBRACE", e3)) {
59279
+ const lines = text.split(/\r?\n/);
59280
+ const curIdx = Math.max(0, e3.line - 1);
59281
+ const openerRe = /^(\s*)namespace\b.*\{\s*$/;
59282
+ let openIdx = -1;
59283
+ let openIndent = "";
59284
+ for (let i3 = curIdx; i3 >= 0; i3--) {
59285
+ const m3 = openerRe.exec(lines[i3] || "");
59286
+ if (m3) {
59287
+ openIdx = i3;
59288
+ openIndent = m3[1] || "";
59289
+ break;
59290
+ }
59291
+ }
59292
+ if (openIdx === -1) {
59293
+ const indent = inferIndentFromLine(lines[curIdx] || "");
59294
+ edits.push(insertAt(text, { line: curIdx + 1, column: 1 }, `${indent}}
59295
+ `));
59296
+ continue;
59297
+ }
59298
+ let insIdx = lines.length;
59299
+ for (let i3 = openIdx + 1; i3 < lines.length; i3++) {
59300
+ const raw = lines[i3] || "";
59301
+ if (raw.trim() === "")
59302
+ continue;
59303
+ const ind = inferIndentFromLine(raw);
59304
+ if (ind.length <= openIndent.length) {
59305
+ insIdx = i3;
59306
+ break;
59307
+ }
59308
+ }
59309
+ edits.push(insertAt(text, { line: insIdx + 1, column: 1 }, `${openIndent}}
58676
59310
  `));
58677
59311
  continue;
58678
59312
  }
@@ -72657,6 +73291,8 @@ var init_ProbeAgent = __esm({
72657
73291
  import_promises2 = require("fs/promises");
72658
73292
  import_path10 = require("path");
72659
73293
  init_tokenCounter();
73294
+ init_InMemoryStorageAdapter();
73295
+ init_HookManager();
72660
73296
  init_tools2();
72661
73297
  init_common2();
72662
73298
  init_probeTool();
@@ -72689,6 +73325,8 @@ var init_ProbeAgent = __esm({
72689
73325
  * @param {string} [options.mcpConfigPath] - Path to MCP configuration file
72690
73326
  * @param {Object} [options.mcpConfig] - MCP configuration object (overrides mcpConfigPath)
72691
73327
  * @param {Array} [options.mcpServers] - Deprecated, use mcpConfig instead
73328
+ * @param {Object} [options.storageAdapter] - Custom storage adapter for history management
73329
+ * @param {Object} [options.hooks] - Hook callbacks for events (e.g., {'tool:start': callback})
72692
73330
  */
72693
73331
  constructor(options = {}) {
72694
73332
  this.sessionId = options.sessionId || (0, import_crypto5.randomUUID)();
@@ -72702,6 +73340,13 @@ var init_ProbeAgent = __esm({
72702
73340
  this.maxResponseTokens = options.maxResponseTokens || parseInt(process.env.MAX_RESPONSE_TOKENS || "0", 10) || null;
72703
73341
  this.maxIterations = options.maxIterations || null;
72704
73342
  this.disableMermaidValidation = !!options.disableMermaidValidation;
73343
+ this.storageAdapter = options.storageAdapter || new InMemoryStorageAdapter();
73344
+ this.hooks = new HookManager();
73345
+ if (options.hooks) {
73346
+ for (const [hookName, callback] of Object.entries(options.hooks)) {
73347
+ this.hooks.on(hookName, callback);
73348
+ }
73349
+ }
72705
73350
  this.enableBash = !!options.enableBash;
72706
73351
  this.bashConfig = options.bashConfig || {};
72707
73352
  if (options.allowedFolders && Array.isArray(options.allowedFolders)) {
@@ -72735,9 +73380,23 @@ var init_ProbeAgent = __esm({
72735
73380
  }
72736
73381
  /**
72737
73382
  * Initialize the agent asynchronously (must be called after constructor)
72738
- * This method initializes MCP and merges MCP tools into the tool list
73383
+ * This method initializes MCP and merges MCP tools into the tool list, and loads history from storage
72739
73384
  */
72740
73385
  async initialize() {
73386
+ try {
73387
+ const history = await this.storageAdapter.loadHistory(this.sessionId);
73388
+ this.history = history;
73389
+ if (this.debug && history.length > 0) {
73390
+ console.log(`[DEBUG] Loaded ${history.length} messages from storage for session ${this.sessionId}`);
73391
+ }
73392
+ await this.hooks.emit(HOOK_TYPES.STORAGE_LOAD, {
73393
+ sessionId: this.sessionId,
73394
+ messages: history
73395
+ });
73396
+ } catch (error2) {
73397
+ console.error(`[ERROR] Failed to load history from storage:`, error2);
73398
+ this.history = [];
73399
+ }
72741
73400
  if (this.enableMcp && !this._mcpInitialized) {
72742
73401
  this._mcpInitialized = true;
72743
73402
  try {
@@ -72770,6 +73429,10 @@ var init_ProbeAgent = __esm({
72770
73429
  this.mcpBridge = null;
72771
73430
  }
72772
73431
  }
73432
+ await this.hooks.emit(HOOK_TYPES.AGENT_INITIALIZED, {
73433
+ sessionId: this.sessionId,
73434
+ agent: this
73435
+ });
72773
73436
  }
72774
73437
  /**
72775
73438
  * Initialize tools with configuration
@@ -72821,7 +73484,7 @@ var init_ProbeAgent = __esm({
72821
73484
  }
72822
73485
  const anthropicApiKey = process.env.ANTHROPIC_API_KEY;
72823
73486
  const openaiApiKey = process.env.OPENAI_API_KEY;
72824
- const googleApiKey = process.env.GOOGLE_API_KEY;
73487
+ const googleApiKey = process.env.GOOGLE_GENERATIVE_AI_API_KEY || process.env.GOOGLE_API_KEY;
72825
73488
  const awsAccessKeyId = process.env.AWS_ACCESS_KEY_ID;
72826
73489
  const awsSecretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
72827
73490
  const awsRegion = process.env.AWS_REGION;
@@ -72869,7 +73532,7 @@ var init_ProbeAgent = __esm({
72869
73532
  } else if (awsAccessKeyId && awsSecretAccessKey && awsRegion || awsApiKey) {
72870
73533
  this.initializeBedrockModel(awsAccessKeyId, awsSecretAccessKey, awsRegion, awsSessionToken, awsApiKey, awsBedrockBaseUrl, modelName);
72871
73534
  } else {
72872
- 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.");
73535
+ 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.");
72873
73536
  }
72874
73537
  }
72875
73538
  /**
@@ -73507,6 +74170,12 @@ You are working with a repository located at: ${searchDirectory}
73507
74170
  options = schemaOrOptions || {};
73508
74171
  }
73509
74172
  try {
74173
+ const oldHistoryLength = this.history.length;
74174
+ await this.hooks.emit(HOOK_TYPES.MESSAGE_USER, {
74175
+ sessionId: this.sessionId,
74176
+ message,
74177
+ images
74178
+ });
73510
74179
  const systemMessage = await this.getSystemMessage();
73511
74180
  let userMessage = { role: "user", content: message.trim() };
73512
74181
  if (images && images.length > 0) {
@@ -73592,6 +74261,9 @@ You are working with a repository located at: ${searchDirectory}
73592
74261
  });
73593
74262
  for await (const delta of result.textStream) {
73594
74263
  assistantResponseContent += delta;
74264
+ if (options.onStream) {
74265
+ options.onStream(delta);
74266
+ }
73595
74267
  }
73596
74268
  const usage = await result.usage;
73597
74269
  if (usage) {
@@ -73656,6 +74328,13 @@ You are working with a repository located at: ${searchDirectory}
73656
74328
  const validation = attemptCompletionSchema.safeParse(params);
73657
74329
  if (validation.success) {
73658
74330
  finalResult = validation.data.result;
74331
+ if (options.onStream && finalResult) {
74332
+ const chunkSize = 50;
74333
+ for (let i3 = 0; i3 < finalResult.length; i3 += chunkSize) {
74334
+ const chunk = finalResult.slice(i3, Math.min(i3 + chunkSize, finalResult.length));
74335
+ options.onStream(chunk);
74336
+ }
74337
+ }
73659
74338
  if (this.debug) console.log(`[DEBUG] Task completed successfully with result: ${finalResult.substring(0, 100)}...`);
73660
74339
  } else {
73661
74340
  console.error(`[ERROR] Invalid attempt_completion parameters:`, validation.error);
@@ -73730,7 +74409,9 @@ ${toolResultContent}
73730
74409
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
73731
74410
  name: toolName,
73732
74411
  args: toolParams,
73733
- status: "started"
74412
+ status: "started",
74413
+ pauseStream: true
74414
+ // Signal to pause text streaming
73734
74415
  });
73735
74416
  const executeToolCall = async () => {
73736
74417
  if (toolName === "delegate") {
@@ -73914,6 +74595,18 @@ IMPORTANT: When using <attempt_complete>, this must be the ONLY content in your
73914
74595
  }
73915
74596
  }
73916
74597
  this.tokenCounter.updateHistory(this.history);
74598
+ try {
74599
+ const messagesToSave = currentMessages.slice(oldHistoryLength);
74600
+ for (const message2 of messagesToSave) {
74601
+ await this.storageAdapter.saveMessage(this.sessionId, message2);
74602
+ await this.hooks.emit(HOOK_TYPES.STORAGE_SAVE, {
74603
+ sessionId: this.sessionId,
74604
+ message: message2
74605
+ });
74606
+ }
74607
+ } catch (error2) {
74608
+ console.error(`[ERROR] Failed to save messages to storage:`, error2);
74609
+ }
73917
74610
  const reachedMaxIterations = currentIteration >= maxIterations && !completionAttempted;
73918
74611
  if (options.schema && !options._schemaFormatted && !completionAttempted && !reachedMaxIterations) {
73919
74612
  if (this.debug) {
@@ -74278,10 +74971,18 @@ Convert your previous response content into actual JSON data that follows this s
74278
74971
  /**
74279
74972
  * Clear conversation history and reset counters
74280
74973
  */
74281
- clearHistory() {
74974
+ async clearHistory() {
74975
+ try {
74976
+ await this.storageAdapter.clearHistory(this.sessionId);
74977
+ } catch (error2) {
74978
+ console.error(`[ERROR] Failed to clear history in storage:`, error2);
74979
+ }
74282
74980
  this.history = [];
74283
74981
  this.tokenCounter.clear();
74284
74982
  clearToolExecutionData(this.sessionId);
74983
+ await this.hooks.emit(HOOK_TYPES.STORAGE_CLEAR, {
74984
+ sessionId: this.sessionId
74985
+ });
74285
74986
  if (this.debug) {
74286
74987
  console.log(`[DEBUG] Cleared conversation history and reset counters for session ${this.sessionId}`);
74287
74988
  }