@probelabs/probe 0.6.0-rc128 → 0.6.0-rc129
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 +179 -5
- package/build/agent/index.js +269 -12
- package/cjs/agent/ProbeAgent.cjs +269 -12
- package/cjs/index.cjs +269 -12
- package/package.json +2 -2
- package/src/agent/ProbeAgent.js +179 -5
package/cjs/index.cjs
CHANGED
|
@@ -54812,7 +54812,7 @@ var init_semantics = __esm({
|
|
|
54812
54812
|
return;
|
|
54813
54813
|
for (const cn of contentNodes) {
|
|
54814
54814
|
const ch = cn.children || {};
|
|
54815
|
-
const inspectTok = (tk) => {
|
|
54815
|
+
const inspectTok = (tk, inQuoted = false) => {
|
|
54816
54816
|
if (!tk)
|
|
54817
54817
|
return false;
|
|
54818
54818
|
const img = String(tk.image || "");
|
|
@@ -54822,7 +54822,7 @@ var init_semantics = __esm({
|
|
|
54822
54822
|
this.ctx.errors.push({
|
|
54823
54823
|
line: tk.startLine ?? 1,
|
|
54824
54824
|
column: col,
|
|
54825
|
-
severity: "warning",
|
|
54825
|
+
severity: inQuoted ? "error" : "warning",
|
|
54826
54826
|
code: "FL-LABEL-BACKTICK",
|
|
54827
54827
|
message: "Backticks (`\u2026`) inside node labels are not supported by Mermaid.",
|
|
54828
54828
|
hint: 'Remove the backticks or use quotes instead, e.g., "GITHUB_ACTIONS" and "--cli".',
|
|
@@ -54834,12 +54834,12 @@ var init_semantics = __esm({
|
|
|
54834
54834
|
};
|
|
54835
54835
|
const texts = ch.Text || [];
|
|
54836
54836
|
for (const tk of texts) {
|
|
54837
|
-
if (inspectTok(tk))
|
|
54837
|
+
if (inspectTok(tk, false))
|
|
54838
54838
|
return;
|
|
54839
54839
|
}
|
|
54840
54840
|
const qs = ch.QuotedString || [];
|
|
54841
54841
|
for (const tk of qs) {
|
|
54842
|
-
if (inspectTok(tk))
|
|
54842
|
+
if (inspectTok(tk, true))
|
|
54843
54843
|
return;
|
|
54844
54844
|
}
|
|
54845
54845
|
}
|
|
@@ -55240,6 +55240,36 @@ function mapFlowchartParserError(err, text) {
|
|
|
55240
55240
|
length: len
|
|
55241
55241
|
};
|
|
55242
55242
|
}
|
|
55243
|
+
{
|
|
55244
|
+
const caret0 = Math.max(0, column - 1);
|
|
55245
|
+
const openIdx = lineStr.lastIndexOf("[", caret0);
|
|
55246
|
+
if (openIdx !== -1) {
|
|
55247
|
+
const closeIdx = lineStr.indexOf("]", openIdx + 1);
|
|
55248
|
+
const seg = closeIdx !== -1 ? lineStr.slice(openIdx + 1, closeIdx) : lineStr.slice(openIdx + 1);
|
|
55249
|
+
if (seg.includes('"')) {
|
|
55250
|
+
return {
|
|
55251
|
+
line,
|
|
55252
|
+
column,
|
|
55253
|
+
severity: "error",
|
|
55254
|
+
code: "FL-LABEL-QUOTE-IN-UNQUOTED",
|
|
55255
|
+
message: "Quotes are not allowed inside unquoted node labels. Use " for quotes or wrap the entire label in quotes.",
|
|
55256
|
+
hint: 'Example: I[Log "processing N items"] or I["Log \\"processing N items\\""]',
|
|
55257
|
+
length: len
|
|
55258
|
+
};
|
|
55259
|
+
}
|
|
55260
|
+
if (seg.includes("(") || seg.includes(")")) {
|
|
55261
|
+
return {
|
|
55262
|
+
line,
|
|
55263
|
+
column,
|
|
55264
|
+
severity: "error",
|
|
55265
|
+
code: "FL-LABEL-PARENS-UNQUOTED",
|
|
55266
|
+
message: "Parentheses inside an unquoted label are not supported by Mermaid.",
|
|
55267
|
+
hint: 'Wrap the label in quotes, e.g., A["Mark (X)"] \u2014 or replace ( and ) with HTML entities: ( and ).',
|
|
55268
|
+
length: len
|
|
55269
|
+
};
|
|
55270
|
+
}
|
|
55271
|
+
}
|
|
55272
|
+
}
|
|
55243
55273
|
if (tokType === "QuotedString") {
|
|
55244
55274
|
return {
|
|
55245
55275
|
line,
|
|
@@ -55272,6 +55302,24 @@ function mapFlowchartParserError(err, text) {
|
|
|
55272
55302
|
length: len
|
|
55273
55303
|
};
|
|
55274
55304
|
}
|
|
55305
|
+
{
|
|
55306
|
+
const caret0 = Math.max(0, column - 1);
|
|
55307
|
+
const openIdx = lineStr.lastIndexOf("(", caret0);
|
|
55308
|
+
if (openIdx !== -1) {
|
|
55309
|
+
const seg = lineStr.slice(openIdx + 1);
|
|
55310
|
+
if (seg.includes("(") || seg.includes(")")) {
|
|
55311
|
+
return {
|
|
55312
|
+
line,
|
|
55313
|
+
column,
|
|
55314
|
+
severity: "error",
|
|
55315
|
+
code: "FL-LABEL-PARENS-UNQUOTED",
|
|
55316
|
+
message: "Parentheses inside an unquoted label are not supported by Mermaid.",
|
|
55317
|
+
hint: 'Wrap the label in quotes, e.g., A["Mark (X)"] \u2014 or replace ( and ) with HTML entities: ( and ).',
|
|
55318
|
+
length: len
|
|
55319
|
+
};
|
|
55320
|
+
}
|
|
55321
|
+
}
|
|
55322
|
+
}
|
|
55275
55323
|
const q3 = findInnerQuoteIssue("(");
|
|
55276
55324
|
if (q3?.kind === "escaped") {
|
|
55277
55325
|
return { line, column: q3.column, severity: "error", code: "FL-LABEL-ESCAPED-QUOTE", message: 'Escaped quotes (\\") in node labels are not supported by Mermaid. Use " instead.', hint: 'Prefer "He said "Hi"".', length: 2 };
|
|
@@ -55293,6 +55341,25 @@ function mapFlowchartParserError(err, text) {
|
|
|
55293
55341
|
length: len
|
|
55294
55342
|
};
|
|
55295
55343
|
}
|
|
55344
|
+
{
|
|
55345
|
+
const caret0 = Math.max(0, column - 1);
|
|
55346
|
+
const openIdx = lineStr.lastIndexOf("{", caret0);
|
|
55347
|
+
if (openIdx !== -1) {
|
|
55348
|
+
const closeIdx = lineStr.indexOf("}", openIdx + 1);
|
|
55349
|
+
const seg = closeIdx !== -1 ? lineStr.slice(openIdx + 1, closeIdx) : lineStr.slice(openIdx + 1);
|
|
55350
|
+
if (seg.includes("(") || seg.includes(")")) {
|
|
55351
|
+
return {
|
|
55352
|
+
line,
|
|
55353
|
+
column,
|
|
55354
|
+
severity: "error",
|
|
55355
|
+
code: "FL-LABEL-PARENS-UNQUOTED",
|
|
55356
|
+
message: "Parentheses inside an unquoted label are not supported by Mermaid.",
|
|
55357
|
+
hint: 'Wrap the label in quotes, e.g., A["Mark (X)"] \u2014 or replace ( and ) with HTML entities: ( and ).',
|
|
55358
|
+
length: len
|
|
55359
|
+
};
|
|
55360
|
+
}
|
|
55361
|
+
}
|
|
55362
|
+
}
|
|
55296
55363
|
const q3 = findInnerQuoteIssue("{");
|
|
55297
55364
|
if (q3?.kind === "escaped") {
|
|
55298
55365
|
return {
|
|
@@ -55631,6 +55698,17 @@ ${br.example}`,
|
|
|
55631
55698
|
if (inRule("arrow") && err.name === "NoViableAltException") {
|
|
55632
55699
|
return { line, column, severity: "error", code: "SE-ARROW-INVALID", message: `Invalid sequence arrow near '${found}'.`, hint: "Use ->, -->, ->>, -->>, -x, --x, -), --), <<->>, or <<-->>", length: len };
|
|
55633
55700
|
}
|
|
55701
|
+
if ((err.name === "NoViableAltException" || err.name === "MismatchedTokenException") && tokType === "Minus") {
|
|
55702
|
+
return {
|
|
55703
|
+
line,
|
|
55704
|
+
column,
|
|
55705
|
+
severity: "error",
|
|
55706
|
+
code: "SE-BULLET-LINE-UNSUPPORTED",
|
|
55707
|
+
message: "Bullet list lines starting with '-' are not supported in sequence diagrams.",
|
|
55708
|
+
hint: "Wrap free\u2011form text in a note block instead, for example:\nNote over A : Item 1\nNote over A\n - Item 1\n - Item 2\nend note",
|
|
55709
|
+
length: len
|
|
55710
|
+
};
|
|
55711
|
+
}
|
|
55634
55712
|
if (inRule("noteStmt")) {
|
|
55635
55713
|
if (err.name === "MismatchedTokenException" && exp("Colon")) {
|
|
55636
55714
|
return { line, column, severity: "error", code: "SE-NOTE-MALFORMED", message: "Malformed note: missing colon before the note text.", hint: "Example: Note right of Alice: Hello", length: len };
|
|
@@ -55788,6 +55866,17 @@ ${br.example}`,
|
|
|
55788
55866
|
};
|
|
55789
55867
|
}
|
|
55790
55868
|
}
|
|
55869
|
+
if ((err.name === "NotAllInputParsedException" || err.name === "NoViableAltException") && found === "-") {
|
|
55870
|
+
return {
|
|
55871
|
+
line,
|
|
55872
|
+
column,
|
|
55873
|
+
severity: "error",
|
|
55874
|
+
code: "SE-BULLET-LINE-UNSUPPORTED",
|
|
55875
|
+
message: "Bullet list lines starting with '-' are not supported in sequence diagrams.",
|
|
55876
|
+
hint: "Wrap free\u2011form text in a note block, for example:\nNote over A : Item 1\nNote over A\n - Item 1\n - Item 2\nend note",
|
|
55877
|
+
length: len
|
|
55878
|
+
};
|
|
55879
|
+
}
|
|
55791
55880
|
if ((err.name === "NoViableAltException" || err.name === "NotAllInputParsedException") && tokType === "ElseKeyword") {
|
|
55792
55881
|
return { line, column, severity: "error", code: "SE-ELSE-OUTSIDE-ALT", message: "'else' is only allowed inside 'alt' blocks.", hint: "Use: alt Condition \u2026 else \u2026 end", length: len };
|
|
55793
55882
|
}
|
|
@@ -55989,6 +56078,30 @@ function validateFlowchart(text, options = {}) {
|
|
|
55989
56078
|
return errs;
|
|
55990
56079
|
},
|
|
55991
56080
|
postParse: (text2, tokens, _cst, prevErrors) => {
|
|
56081
|
+
{
|
|
56082
|
+
const tks = tokens;
|
|
56083
|
+
const firstByLine = /* @__PURE__ */ new Map();
|
|
56084
|
+
for (const tk of tks) {
|
|
56085
|
+
const ln = tk.startLine ?? 1;
|
|
56086
|
+
const col = tk.startColumn ?? 1;
|
|
56087
|
+
const prev = firstByLine.get(ln);
|
|
56088
|
+
if (!prev || (prev.startColumn ?? Infinity) > col)
|
|
56089
|
+
firstByLine.set(ln, tk);
|
|
56090
|
+
}
|
|
56091
|
+
for (const tk of tks) {
|
|
56092
|
+
if (tk.image === "title" && firstByLine.get(tk.startLine ?? 1) === tk) {
|
|
56093
|
+
prevErrors.push({
|
|
56094
|
+
line: tk.startLine ?? 1,
|
|
56095
|
+
column: tk.startColumn ?? 1,
|
|
56096
|
+
severity: "error",
|
|
56097
|
+
code: "FL-META-UNSUPPORTED",
|
|
56098
|
+
message: "'title' is not supported in flowcharts by the current Mermaid CLI.",
|
|
56099
|
+
hint: 'Use a Markdown heading above the code block, or draw a labeled node at the top (e.g., T["Dependency Relationship"]).',
|
|
56100
|
+
length: tk.image?.length ?? 5
|
|
56101
|
+
});
|
|
56102
|
+
}
|
|
56103
|
+
}
|
|
56104
|
+
}
|
|
55992
56105
|
const escWarn = detectEscapedQuotes(tokens, {
|
|
55993
56106
|
code: "FL-LABEL-ESCAPED-QUOTE",
|
|
55994
56107
|
message: 'Escaped quotes (\\") in node labels are accepted by Mermaid, but using " is preferred for portability.',
|
|
@@ -58407,6 +58520,13 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
58407
58520
|
const replaced = inner.split('\\"').join(""");
|
|
58408
58521
|
edits.push({ start: { line: e3.line, column: q1 + 2 }, end: { line: e3.line, column: q22 + 1 }, newText: replaced });
|
|
58409
58522
|
continue;
|
|
58523
|
+
if (is("FL-META-UNSUPPORTED", e3)) {
|
|
58524
|
+
if (level === "all") {
|
|
58525
|
+
const lineText2 = lineTextAt(text, e3.line);
|
|
58526
|
+
edits.push({ start: { line: e3.line, column: 1 }, end: { line: e3.line + 1, column: 1 }, newText: "" });
|
|
58527
|
+
}
|
|
58528
|
+
continue;
|
|
58529
|
+
}
|
|
58410
58530
|
}
|
|
58411
58531
|
}
|
|
58412
58532
|
}
|
|
@@ -58414,6 +58534,12 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
58414
58534
|
edits.push(replaceRange(text, at(e3), e3.length ?? 2, """));
|
|
58415
58535
|
continue;
|
|
58416
58536
|
}
|
|
58537
|
+
if (is("FL-META-UNSUPPORTED", e3)) {
|
|
58538
|
+
if (level === "all") {
|
|
58539
|
+
edits.push({ start: { line: e3.line, column: 1 }, end: { line: e3.line + 1, column: 1 }, newText: "" });
|
|
58540
|
+
}
|
|
58541
|
+
continue;
|
|
58542
|
+
}
|
|
58417
58543
|
if (is("FL-LABEL-BACKTICK", e3)) {
|
|
58418
58544
|
edits.push(replaceRange(text, at(e3), e3.length ?? 1, ""));
|
|
58419
58545
|
continue;
|
|
@@ -58463,6 +58589,12 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
58463
58589
|
edits.push(replaceRange(text, at(e3), e3.length ?? 1, rep));
|
|
58464
58590
|
continue;
|
|
58465
58591
|
}
|
|
58592
|
+
if (is("FL-END-WITHOUT-SUBGRAPH", e3)) {
|
|
58593
|
+
if (level === "all") {
|
|
58594
|
+
edits.push({ start: { line: e3.line, column: 1 }, end: { line: e3.line + 1, column: 1 }, newText: "" });
|
|
58595
|
+
}
|
|
58596
|
+
continue;
|
|
58597
|
+
}
|
|
58466
58598
|
if (is("FL-LABEL-DOUBLE-IN-DOUBLE", e3)) {
|
|
58467
58599
|
const lineText = lineTextAt(text, e3.line);
|
|
58468
58600
|
const caret0 = Math.max(0, e3.column - 1);
|
|
@@ -58799,6 +58931,9 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
58799
58931
|
continue;
|
|
58800
58932
|
}
|
|
58801
58933
|
if (is("FL-QUOTE-UNCLOSED", e3)) {
|
|
58934
|
+
if (patchedLines.has(e3.line)) {
|
|
58935
|
+
continue;
|
|
58936
|
+
}
|
|
58802
58937
|
if (level === "all") {
|
|
58803
58938
|
const lineText = lineTextAt(text, e3.line);
|
|
58804
58939
|
const caret0 = Math.max(0, e3.column - 1);
|
|
@@ -58873,7 +59008,7 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
58873
59008
|
newInner = ltrim + left + replacedMid + right + rtrim;
|
|
58874
59009
|
} else {
|
|
58875
59010
|
const replaced = inner.split(""").join("\0").split('"').join(""").split("\0").join(""");
|
|
58876
|
-
newInner =
|
|
59011
|
+
newInner = replaced;
|
|
58877
59012
|
}
|
|
58878
59013
|
edits.push({ start: { line: e3.line, column: contentStart + 1 }, end: { line: e3.line, column: closeIdx + 1 }, newText: newInner });
|
|
58879
59014
|
patchedLines.add(e3.line);
|
|
@@ -73422,7 +73557,7 @@ var init_ProbeAgent = __esm({
|
|
|
73422
73557
|
MAX_HISTORY_MESSAGES = 100;
|
|
73423
73558
|
SUPPORTED_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "webp", "gif", "bmp", "svg"];
|
|
73424
73559
|
MAX_IMAGE_FILE_SIZE = 20 * 1024 * 1024;
|
|
73425
|
-
ProbeAgent = class {
|
|
73560
|
+
ProbeAgent = class _ProbeAgent {
|
|
73426
73561
|
/**
|
|
73427
73562
|
* Create a new ProbeAgent instance
|
|
73428
73563
|
* @param {Object} options - Configuration options
|
|
@@ -74304,12 +74439,24 @@ You are working with a repository located at: ${searchDirectory}
|
|
|
74304
74439
|
}))
|
|
74305
74440
|
];
|
|
74306
74441
|
}
|
|
74307
|
-
|
|
74308
|
-
|
|
74309
|
-
|
|
74310
|
-
|
|
74311
|
-
|
|
74312
|
-
|
|
74442
|
+
const hasSystemMessage = this.history.length > 0 && this.history[0].role === "system";
|
|
74443
|
+
let currentMessages;
|
|
74444
|
+
if (hasSystemMessage) {
|
|
74445
|
+
currentMessages = [
|
|
74446
|
+
...this.history,
|
|
74447
|
+
userMessage
|
|
74448
|
+
];
|
|
74449
|
+
if (this.debug) {
|
|
74450
|
+
console.log("[DEBUG] Reusing existing system message from history for cache efficiency");
|
|
74451
|
+
}
|
|
74452
|
+
} else {
|
|
74453
|
+
currentMessages = [
|
|
74454
|
+
{ role: "system", content: systemMessage },
|
|
74455
|
+
...this.history,
|
|
74456
|
+
// Include previous conversation history
|
|
74457
|
+
userMessage
|
|
74458
|
+
];
|
|
74459
|
+
}
|
|
74313
74460
|
let currentIteration = 0;
|
|
74314
74461
|
let completionAttempted = false;
|
|
74315
74462
|
let finalResult = "I was unable to complete your request due to reaching the maximum number of tool iterations.";
|
|
@@ -75104,6 +75251,116 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
75104
75251
|
console.log(`[DEBUG] Cleared conversation history and reset counters for session ${this.sessionId}`);
|
|
75105
75252
|
}
|
|
75106
75253
|
}
|
|
75254
|
+
/**
|
|
75255
|
+
* Clone this agent's session to create a new agent with shared conversation history
|
|
75256
|
+
* @param {Object} options - Clone options
|
|
75257
|
+
* @param {string} [options.sessionId] - Session ID for the cloned agent (defaults to new UUID)
|
|
75258
|
+
* @param {boolean} [options.stripInternalMessages=true] - Remove internal messages (schema reminders, mermaid fixes, etc.)
|
|
75259
|
+
* @param {boolean} [options.keepSystemMessage=true] - Keep the system message in cloned history
|
|
75260
|
+
* @param {boolean} [options.deepCopy=true] - Deep copy messages to prevent mutations
|
|
75261
|
+
* @param {Object} [options.overrides] - Override any ProbeAgent constructor options
|
|
75262
|
+
* @returns {ProbeAgent} New agent instance with cloned history
|
|
75263
|
+
*/
|
|
75264
|
+
clone(options = {}) {
|
|
75265
|
+
const {
|
|
75266
|
+
sessionId = (0, import_crypto5.randomUUID)(),
|
|
75267
|
+
stripInternalMessages = true,
|
|
75268
|
+
keepSystemMessage = true,
|
|
75269
|
+
deepCopy = true,
|
|
75270
|
+
overrides = {}
|
|
75271
|
+
} = options;
|
|
75272
|
+
let clonedHistory = deepCopy ? JSON.parse(JSON.stringify(this.history)) : [...this.history];
|
|
75273
|
+
if (stripInternalMessages) {
|
|
75274
|
+
clonedHistory = this._stripInternalMessages(clonedHistory, keepSystemMessage);
|
|
75275
|
+
}
|
|
75276
|
+
const clonedAgent = new _ProbeAgent({
|
|
75277
|
+
// Copy current agent's config
|
|
75278
|
+
customPrompt: this.customPrompt,
|
|
75279
|
+
promptType: this.promptType,
|
|
75280
|
+
allowEdit: this.allowEdit,
|
|
75281
|
+
path: this.allowedFolders[0],
|
|
75282
|
+
// Use first allowed folder as primary path
|
|
75283
|
+
allowedFolders: [...this.allowedFolders],
|
|
75284
|
+
provider: this.clientApiProvider,
|
|
75285
|
+
model: this.modelName,
|
|
75286
|
+
debug: this.debug,
|
|
75287
|
+
outline: this.outline,
|
|
75288
|
+
maxResponseTokens: this.maxResponseTokens,
|
|
75289
|
+
maxIterations: this.maxIterations,
|
|
75290
|
+
disableMermaidValidation: this.disableMermaidValidation,
|
|
75291
|
+
enableMcp: !!this.mcpBridge,
|
|
75292
|
+
mcpConfig: this.mcpConfig,
|
|
75293
|
+
enableBash: this.enableBash,
|
|
75294
|
+
bashConfig: this.bashConfig,
|
|
75295
|
+
storageAdapter: this.storageAdapter,
|
|
75296
|
+
// Override with any provided options
|
|
75297
|
+
sessionId,
|
|
75298
|
+
...overrides
|
|
75299
|
+
});
|
|
75300
|
+
clonedAgent.history = clonedHistory;
|
|
75301
|
+
if (this.debug) {
|
|
75302
|
+
console.log(`[DEBUG] Cloned session ${this.sessionId} -> ${sessionId}`);
|
|
75303
|
+
console.log(`[DEBUG] Cloned ${clonedHistory.length} messages (stripInternal: ${stripInternalMessages})`);
|
|
75304
|
+
}
|
|
75305
|
+
return clonedAgent;
|
|
75306
|
+
}
|
|
75307
|
+
/**
|
|
75308
|
+
* Internal method to strip internal/temporary messages from history
|
|
75309
|
+
* Removes: schema reminders, mermaid fix prompts, tool use reminders, etc.
|
|
75310
|
+
* Keeps: system message, user messages, assistant responses, tool results
|
|
75311
|
+
* @private
|
|
75312
|
+
*/
|
|
75313
|
+
_stripInternalMessages(history, keepSystemMessage = true) {
|
|
75314
|
+
const filtered = [];
|
|
75315
|
+
for (let i3 = 0; i3 < history.length; i3++) {
|
|
75316
|
+
const message = history[i3];
|
|
75317
|
+
if (message.role === "system") {
|
|
75318
|
+
if (keepSystemMessage) {
|
|
75319
|
+
filtered.push(message);
|
|
75320
|
+
} else if (this.debug) {
|
|
75321
|
+
console.log(`[DEBUG] Removing system message at index ${i3}`);
|
|
75322
|
+
}
|
|
75323
|
+
continue;
|
|
75324
|
+
}
|
|
75325
|
+
if (this._isInternalMessage(message, i3, history)) {
|
|
75326
|
+
if (this.debug) {
|
|
75327
|
+
console.log(`[DEBUG] Stripping internal message at index ${i3}: ${message.role}`);
|
|
75328
|
+
}
|
|
75329
|
+
continue;
|
|
75330
|
+
}
|
|
75331
|
+
filtered.push(message);
|
|
75332
|
+
}
|
|
75333
|
+
return filtered;
|
|
75334
|
+
}
|
|
75335
|
+
/**
|
|
75336
|
+
* Determine if a message is an internal/temporary message
|
|
75337
|
+
* @private
|
|
75338
|
+
*/
|
|
75339
|
+
_isInternalMessage(message, index, history) {
|
|
75340
|
+
if (message.role !== "user") {
|
|
75341
|
+
return false;
|
|
75342
|
+
}
|
|
75343
|
+
if (!message.content) {
|
|
75344
|
+
return false;
|
|
75345
|
+
}
|
|
75346
|
+
const content = typeof message.content === "string" ? message.content : JSON.stringify(message.content);
|
|
75347
|
+
if (content.includes("IMPORTANT: A schema was provided") || content.includes("You MUST respond with data that matches this schema") || content.includes("Your response must conform to this schema:")) {
|
|
75348
|
+
return true;
|
|
75349
|
+
}
|
|
75350
|
+
if (content.includes("Please use one of the available tools") && content.includes("or use attempt_completion") && content.includes("Remember: Use proper XML format")) {
|
|
75351
|
+
return true;
|
|
75352
|
+
}
|
|
75353
|
+
if (content.includes("The mermaid diagram in your response has syntax errors") || content.includes("Please fix the mermaid syntax errors") || content.includes("Here is the corrected version:")) {
|
|
75354
|
+
return true;
|
|
75355
|
+
}
|
|
75356
|
+
if (content.includes("Your response does not match the expected JSON schema") || content.includes("Please provide a valid JSON response") || content.includes("Schema validation error:")) {
|
|
75357
|
+
return true;
|
|
75358
|
+
}
|
|
75359
|
+
if (content.includes("When using <attempt_complete>") && content.includes("this must be the ONLY content in your response")) {
|
|
75360
|
+
return true;
|
|
75361
|
+
}
|
|
75362
|
+
return false;
|
|
75363
|
+
}
|
|
75107
75364
|
/**
|
|
75108
75365
|
* Clean up resources (including MCP connections)
|
|
75109
75366
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@probelabs/probe",
|
|
3
|
-
"version": "0.6.0-
|
|
3
|
+
"version": "0.6.0-rc129",
|
|
4
4
|
"description": "Node.js wrapper for the probe code search tool",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"module": "src/index.js",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"@opentelemetry/sdk-node": "^0.203.0",
|
|
81
81
|
"@opentelemetry/sdk-trace-base": "^1.30.0",
|
|
82
82
|
"@opentelemetry/semantic-conventions": "^1.36.0",
|
|
83
|
-
"@probelabs/maid": "^0.0.
|
|
83
|
+
"@probelabs/maid": "^0.0.15",
|
|
84
84
|
"ai": "^5.0.0",
|
|
85
85
|
"axios": "^1.8.3",
|
|
86
86
|
"fs-extra": "^11.1.1",
|
package/src/agent/ProbeAgent.js
CHANGED
|
@@ -1152,11 +1152,28 @@ When troubleshooting:
|
|
|
1152
1152
|
}
|
|
1153
1153
|
|
|
1154
1154
|
// Initialize conversation with existing history + new user message
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1155
|
+
// If history already contains a system message (from session cloning), reuse it for cache efficiency
|
|
1156
|
+
// Otherwise add a fresh system message
|
|
1157
|
+
const hasSystemMessage = this.history.length > 0 && this.history[0].role === 'system';
|
|
1158
|
+
let currentMessages;
|
|
1159
|
+
|
|
1160
|
+
if (hasSystemMessage) {
|
|
1161
|
+
// Reuse existing system message from history for cache efficiency
|
|
1162
|
+
currentMessages = [
|
|
1163
|
+
...this.history,
|
|
1164
|
+
userMessage
|
|
1165
|
+
];
|
|
1166
|
+
if (this.debug) {
|
|
1167
|
+
console.log('[DEBUG] Reusing existing system message from history for cache efficiency');
|
|
1168
|
+
}
|
|
1169
|
+
} else {
|
|
1170
|
+
// Add fresh system message (first call or empty history)
|
|
1171
|
+
currentMessages = [
|
|
1172
|
+
{ role: 'system', content: systemMessage },
|
|
1173
|
+
...this.history, // Include previous conversation history
|
|
1174
|
+
userMessage
|
|
1175
|
+
];
|
|
1176
|
+
}
|
|
1160
1177
|
|
|
1161
1178
|
let currentIteration = 0;
|
|
1162
1179
|
let completionAttempted = false;
|
|
@@ -2147,6 +2164,163 @@ Convert your previous response content into actual JSON data that follows this s
|
|
|
2147
2164
|
}
|
|
2148
2165
|
}
|
|
2149
2166
|
|
|
2167
|
+
/**
|
|
2168
|
+
* Clone this agent's session to create a new agent with shared conversation history
|
|
2169
|
+
* @param {Object} options - Clone options
|
|
2170
|
+
* @param {string} [options.sessionId] - Session ID for the cloned agent (defaults to new UUID)
|
|
2171
|
+
* @param {boolean} [options.stripInternalMessages=true] - Remove internal messages (schema reminders, mermaid fixes, etc.)
|
|
2172
|
+
* @param {boolean} [options.keepSystemMessage=true] - Keep the system message in cloned history
|
|
2173
|
+
* @param {boolean} [options.deepCopy=true] - Deep copy messages to prevent mutations
|
|
2174
|
+
* @param {Object} [options.overrides] - Override any ProbeAgent constructor options
|
|
2175
|
+
* @returns {ProbeAgent} New agent instance with cloned history
|
|
2176
|
+
*/
|
|
2177
|
+
clone(options = {}) {
|
|
2178
|
+
const {
|
|
2179
|
+
sessionId = randomUUID(),
|
|
2180
|
+
stripInternalMessages = true,
|
|
2181
|
+
keepSystemMessage = true,
|
|
2182
|
+
deepCopy = true,
|
|
2183
|
+
overrides = {}
|
|
2184
|
+
} = options;
|
|
2185
|
+
|
|
2186
|
+
// Clone the history
|
|
2187
|
+
let clonedHistory = deepCopy
|
|
2188
|
+
? JSON.parse(JSON.stringify(this.history))
|
|
2189
|
+
: [...this.history];
|
|
2190
|
+
|
|
2191
|
+
// Strip internal messages if requested
|
|
2192
|
+
if (stripInternalMessages) {
|
|
2193
|
+
clonedHistory = this._stripInternalMessages(clonedHistory, keepSystemMessage);
|
|
2194
|
+
}
|
|
2195
|
+
|
|
2196
|
+
// Create new agent with same configuration
|
|
2197
|
+
const clonedAgent = new ProbeAgent({
|
|
2198
|
+
// Copy current agent's config
|
|
2199
|
+
customPrompt: this.customPrompt,
|
|
2200
|
+
promptType: this.promptType,
|
|
2201
|
+
allowEdit: this.allowEdit,
|
|
2202
|
+
path: this.allowedFolders[0], // Use first allowed folder as primary path
|
|
2203
|
+
allowedFolders: [...this.allowedFolders],
|
|
2204
|
+
provider: this.clientApiProvider,
|
|
2205
|
+
model: this.modelName,
|
|
2206
|
+
debug: this.debug,
|
|
2207
|
+
outline: this.outline,
|
|
2208
|
+
maxResponseTokens: this.maxResponseTokens,
|
|
2209
|
+
maxIterations: this.maxIterations,
|
|
2210
|
+
disableMermaidValidation: this.disableMermaidValidation,
|
|
2211
|
+
enableMcp: !!this.mcpBridge,
|
|
2212
|
+
mcpConfig: this.mcpConfig,
|
|
2213
|
+
enableBash: this.enableBash,
|
|
2214
|
+
bashConfig: this.bashConfig,
|
|
2215
|
+
storageAdapter: this.storageAdapter,
|
|
2216
|
+
// Override with any provided options
|
|
2217
|
+
sessionId,
|
|
2218
|
+
...overrides
|
|
2219
|
+
});
|
|
2220
|
+
|
|
2221
|
+
// Set the cloned history directly (before initialization to avoid overwriting)
|
|
2222
|
+
clonedAgent.history = clonedHistory;
|
|
2223
|
+
|
|
2224
|
+
if (this.debug) {
|
|
2225
|
+
console.log(`[DEBUG] Cloned session ${this.sessionId} -> ${sessionId}`);
|
|
2226
|
+
console.log(`[DEBUG] Cloned ${clonedHistory.length} messages (stripInternal: ${stripInternalMessages})`);
|
|
2227
|
+
}
|
|
2228
|
+
|
|
2229
|
+
return clonedAgent;
|
|
2230
|
+
}
|
|
2231
|
+
|
|
2232
|
+
/**
|
|
2233
|
+
* Internal method to strip internal/temporary messages from history
|
|
2234
|
+
* Removes: schema reminders, mermaid fix prompts, tool use reminders, etc.
|
|
2235
|
+
* Keeps: system message, user messages, assistant responses, tool results
|
|
2236
|
+
* @private
|
|
2237
|
+
*/
|
|
2238
|
+
_stripInternalMessages(history, keepSystemMessage = true) {
|
|
2239
|
+
const filtered = [];
|
|
2240
|
+
|
|
2241
|
+
for (let i = 0; i < history.length; i++) {
|
|
2242
|
+
const message = history[i];
|
|
2243
|
+
|
|
2244
|
+
// Handle system message
|
|
2245
|
+
if (message.role === 'system') {
|
|
2246
|
+
if (keepSystemMessage) {
|
|
2247
|
+
filtered.push(message);
|
|
2248
|
+
} else if (this.debug) {
|
|
2249
|
+
console.log(`[DEBUG] Removing system message at index ${i}`);
|
|
2250
|
+
}
|
|
2251
|
+
continue;
|
|
2252
|
+
}
|
|
2253
|
+
|
|
2254
|
+
// Check if this is an internal message that should be stripped
|
|
2255
|
+
if (this._isInternalMessage(message, i, history)) {
|
|
2256
|
+
if (this.debug) {
|
|
2257
|
+
console.log(`[DEBUG] Stripping internal message at index ${i}: ${message.role}`);
|
|
2258
|
+
}
|
|
2259
|
+
continue;
|
|
2260
|
+
}
|
|
2261
|
+
|
|
2262
|
+
// Keep this message
|
|
2263
|
+
filtered.push(message);
|
|
2264
|
+
}
|
|
2265
|
+
|
|
2266
|
+
return filtered;
|
|
2267
|
+
}
|
|
2268
|
+
|
|
2269
|
+
/**
|
|
2270
|
+
* Determine if a message is an internal/temporary message
|
|
2271
|
+
* @private
|
|
2272
|
+
*/
|
|
2273
|
+
_isInternalMessage(message, index, history) {
|
|
2274
|
+
if (message.role !== 'user') {
|
|
2275
|
+
return false; // Only user messages can be internal reminders
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2278
|
+
// Handle null/undefined content
|
|
2279
|
+
if (!message.content) {
|
|
2280
|
+
return false;
|
|
2281
|
+
}
|
|
2282
|
+
|
|
2283
|
+
const content = typeof message.content === 'string'
|
|
2284
|
+
? message.content
|
|
2285
|
+
: JSON.stringify(message.content);
|
|
2286
|
+
|
|
2287
|
+
// Schema reminder messages
|
|
2288
|
+
if (content.includes('IMPORTANT: A schema was provided') ||
|
|
2289
|
+
content.includes('You MUST respond with data that matches this schema') ||
|
|
2290
|
+
content.includes('Your response must conform to this schema:')) {
|
|
2291
|
+
return true;
|
|
2292
|
+
}
|
|
2293
|
+
|
|
2294
|
+
// Tool use reminder messages
|
|
2295
|
+
if (content.includes('Please use one of the available tools') &&
|
|
2296
|
+
content.includes('or use attempt_completion') &&
|
|
2297
|
+
content.includes('Remember: Use proper XML format')) {
|
|
2298
|
+
return true;
|
|
2299
|
+
}
|
|
2300
|
+
|
|
2301
|
+
// Mermaid fix prompts
|
|
2302
|
+
if (content.includes('The mermaid diagram in your response has syntax errors') ||
|
|
2303
|
+
content.includes('Please fix the mermaid syntax errors') ||
|
|
2304
|
+
content.includes('Here is the corrected version:')) {
|
|
2305
|
+
return true;
|
|
2306
|
+
}
|
|
2307
|
+
|
|
2308
|
+
// JSON correction prompts
|
|
2309
|
+
if (content.includes('Your response does not match the expected JSON schema') ||
|
|
2310
|
+
content.includes('Please provide a valid JSON response') ||
|
|
2311
|
+
content.includes('Schema validation error:')) {
|
|
2312
|
+
return true;
|
|
2313
|
+
}
|
|
2314
|
+
|
|
2315
|
+
// Empty attempt_complete reminders
|
|
2316
|
+
if (content.includes('When using <attempt_complete>') &&
|
|
2317
|
+
content.includes('this must be the ONLY content in your response')) {
|
|
2318
|
+
return true;
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
return false;
|
|
2322
|
+
}
|
|
2323
|
+
|
|
2150
2324
|
/**
|
|
2151
2325
|
* Clean up resources (including MCP connections)
|
|
2152
2326
|
*/
|