@rama_nigg/open-cursor 2.3.5 → 2.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/index.js +28 -7
- package/dist/plugin-entry.js +28 -7
- package/package.json +1 -1
- package/src/provider/tool-loop-guard.ts +37 -2
package/README.md
CHANGED
|
@@ -27,6 +27,9 @@ Add to `~/.config/opencode/opencode.json`:
|
|
|
27
27
|
"cursor-acp": {
|
|
28
28
|
"name": "Cursor ACP",
|
|
29
29
|
"npm": "@ai-sdk/openai-compatible",
|
|
30
|
+
"options": {
|
|
31
|
+
"baseURL": "http://127.0.0.1:32124/v1"
|
|
32
|
+
},
|
|
30
33
|
"models": {
|
|
31
34
|
"cursor-acp/auto": { "name": "Auto" },
|
|
32
35
|
"cursor-acp/composer-1.5": { "name": "Composer 1.5" },
|
package/dist/index.js
CHANGED
|
@@ -17448,13 +17448,13 @@ function createToolLoopGuard(messages, maxRepeat) {
|
|
|
17448
17448
|
}
|
|
17449
17449
|
const strictFingerprint = `${toolCall.function.name}|${argShape}|${errorClass}`;
|
|
17450
17450
|
const coarseFingerprint = `${toolCall.function.name}|${errorClass}`;
|
|
17451
|
-
return evaluateWithFingerprints(errorClass, strictFingerprint, coarseFingerprint, counts, coarseCounts, maxRepeat, coarseMaxRepeat);
|
|
17451
|
+
return evaluateWithFingerprints(toolCall.function.name, errorClass, strictFingerprint, coarseFingerprint, counts, coarseCounts, maxRepeat, coarseMaxRepeat);
|
|
17452
17452
|
},
|
|
17453
17453
|
evaluateValidation(toolCall, validationSignature) {
|
|
17454
17454
|
const normalizedSignature = normalizeValidationSignature(validationSignature);
|
|
17455
17455
|
const strictFingerprint = `${toolCall.function.name}|schema:${normalizedSignature}|validation`;
|
|
17456
17456
|
const coarseFingerprint = `${toolCall.function.name}|validation`;
|
|
17457
|
-
return evaluateWithFingerprints("validation", strictFingerprint, coarseFingerprint, validationCounts, validationCoarseCounts, maxRepeat, coarseMaxRepeat);
|
|
17457
|
+
return evaluateWithFingerprints(toolCall.function.name, "validation", strictFingerprint, coarseFingerprint, validationCounts, validationCoarseCounts, maxRepeat, coarseMaxRepeat);
|
|
17458
17458
|
},
|
|
17459
17459
|
resetFingerprint(fingerprint) {
|
|
17460
17460
|
counts.delete(fingerprint);
|
|
@@ -17685,7 +17685,7 @@ function normalizeValidationSignature(signature) {
|
|
|
17685
17685
|
const normalized = signature.trim().toLowerCase();
|
|
17686
17686
|
return normalized.length > 0 ? normalized : "invalid";
|
|
17687
17687
|
}
|
|
17688
|
-
function evaluateWithFingerprints(errorClass, strictFingerprint, coarseFingerprint, strictCounts, coarseCounts, maxRepeat, coarseMaxRepeat) {
|
|
17688
|
+
function evaluateWithFingerprints(toolName, errorClass, strictFingerprint, coarseFingerprint, strictCounts, coarseCounts, maxRepeat, coarseMaxRepeat) {
|
|
17689
17689
|
if (errorClass === "success") {
|
|
17690
17690
|
return {
|
|
17691
17691
|
fingerprint: strictFingerprint,
|
|
@@ -17698,9 +17698,20 @@ function evaluateWithFingerprints(errorClass, strictFingerprint, coarseFingerpri
|
|
|
17698
17698
|
}
|
|
17699
17699
|
const strictRepeatCount = (strictCounts.get(strictFingerprint) ?? 0) + 1;
|
|
17700
17700
|
strictCounts.set(strictFingerprint, strictRepeatCount);
|
|
17701
|
+
const strictTriggered = strictRepeatCount > maxRepeat;
|
|
17702
|
+
const isExplorationTool = EXPLORATION_TOOLS.has(toolName.toLowerCase());
|
|
17703
|
+
if (isExplorationTool) {
|
|
17704
|
+
return {
|
|
17705
|
+
fingerprint: strictFingerprint,
|
|
17706
|
+
repeatCount: strictRepeatCount,
|
|
17707
|
+
maxRepeat,
|
|
17708
|
+
errorClass,
|
|
17709
|
+
triggered: strictTriggered,
|
|
17710
|
+
tracked: true
|
|
17711
|
+
};
|
|
17712
|
+
}
|
|
17701
17713
|
const coarseRepeatCount = (coarseCounts.get(coarseFingerprint) ?? 0) + 1;
|
|
17702
17714
|
coarseCounts.set(coarseFingerprint, coarseRepeatCount);
|
|
17703
|
-
const strictTriggered = strictRepeatCount > maxRepeat;
|
|
17704
17715
|
const coarseTriggered = coarseRepeatCount > coarseMaxRepeat;
|
|
17705
17716
|
const preferCoarseFingerprint = coarseTriggered && !strictTriggered;
|
|
17706
17717
|
return {
|
|
@@ -17791,7 +17802,7 @@ function containsAny(text, patterns) {
|
|
|
17791
17802
|
function isRecord4(value) {
|
|
17792
17803
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17793
17804
|
}
|
|
17794
|
-
var UNKNOWN_AS_SUCCESS_TOOLS, COARSE_LIMIT_MULTIPLIER = 3;
|
|
17805
|
+
var UNKNOWN_AS_SUCCESS_TOOLS, EXPLORATION_TOOLS, COARSE_LIMIT_MULTIPLIER = 3;
|
|
17795
17806
|
var init_tool_loop_guard = __esm(() => {
|
|
17796
17807
|
UNKNOWN_AS_SUCCESS_TOOLS = new Set([
|
|
17797
17808
|
"bash",
|
|
@@ -17803,9 +17814,19 @@ var init_tool_loop_guard = __esm(() => {
|
|
|
17803
17814
|
"ls",
|
|
17804
17815
|
"glob",
|
|
17805
17816
|
"stat",
|
|
17806
|
-
"webfetch",
|
|
17807
17817
|
"mkdir",
|
|
17808
|
-
"rm"
|
|
17818
|
+
"rm",
|
|
17819
|
+
"webfetch",
|
|
17820
|
+
"semsearch",
|
|
17821
|
+
"readlints"
|
|
17822
|
+
]);
|
|
17823
|
+
EXPLORATION_TOOLS = new Set([
|
|
17824
|
+
"read",
|
|
17825
|
+
"grep",
|
|
17826
|
+
"glob",
|
|
17827
|
+
"ls",
|
|
17828
|
+
"stat",
|
|
17829
|
+
"semsearch"
|
|
17809
17830
|
]);
|
|
17810
17831
|
});
|
|
17811
17832
|
|
package/dist/plugin-entry.js
CHANGED
|
@@ -17448,13 +17448,13 @@ function createToolLoopGuard(messages, maxRepeat) {
|
|
|
17448
17448
|
}
|
|
17449
17449
|
const strictFingerprint = `${toolCall.function.name}|${argShape}|${errorClass}`;
|
|
17450
17450
|
const coarseFingerprint = `${toolCall.function.name}|${errorClass}`;
|
|
17451
|
-
return evaluateWithFingerprints(errorClass, strictFingerprint, coarseFingerprint, counts, coarseCounts, maxRepeat, coarseMaxRepeat);
|
|
17451
|
+
return evaluateWithFingerprints(toolCall.function.name, errorClass, strictFingerprint, coarseFingerprint, counts, coarseCounts, maxRepeat, coarseMaxRepeat);
|
|
17452
17452
|
},
|
|
17453
17453
|
evaluateValidation(toolCall, validationSignature) {
|
|
17454
17454
|
const normalizedSignature = normalizeValidationSignature(validationSignature);
|
|
17455
17455
|
const strictFingerprint = `${toolCall.function.name}|schema:${normalizedSignature}|validation`;
|
|
17456
17456
|
const coarseFingerprint = `${toolCall.function.name}|validation`;
|
|
17457
|
-
return evaluateWithFingerprints("validation", strictFingerprint, coarseFingerprint, validationCounts, validationCoarseCounts, maxRepeat, coarseMaxRepeat);
|
|
17457
|
+
return evaluateWithFingerprints(toolCall.function.name, "validation", strictFingerprint, coarseFingerprint, validationCounts, validationCoarseCounts, maxRepeat, coarseMaxRepeat);
|
|
17458
17458
|
},
|
|
17459
17459
|
resetFingerprint(fingerprint) {
|
|
17460
17460
|
counts.delete(fingerprint);
|
|
@@ -17685,7 +17685,7 @@ function normalizeValidationSignature(signature) {
|
|
|
17685
17685
|
const normalized = signature.trim().toLowerCase();
|
|
17686
17686
|
return normalized.length > 0 ? normalized : "invalid";
|
|
17687
17687
|
}
|
|
17688
|
-
function evaluateWithFingerprints(errorClass, strictFingerprint, coarseFingerprint, strictCounts, coarseCounts, maxRepeat, coarseMaxRepeat) {
|
|
17688
|
+
function evaluateWithFingerprints(toolName, errorClass, strictFingerprint, coarseFingerprint, strictCounts, coarseCounts, maxRepeat, coarseMaxRepeat) {
|
|
17689
17689
|
if (errorClass === "success") {
|
|
17690
17690
|
return {
|
|
17691
17691
|
fingerprint: strictFingerprint,
|
|
@@ -17698,9 +17698,20 @@ function evaluateWithFingerprints(errorClass, strictFingerprint, coarseFingerpri
|
|
|
17698
17698
|
}
|
|
17699
17699
|
const strictRepeatCount = (strictCounts.get(strictFingerprint) ?? 0) + 1;
|
|
17700
17700
|
strictCounts.set(strictFingerprint, strictRepeatCount);
|
|
17701
|
+
const strictTriggered = strictRepeatCount > maxRepeat;
|
|
17702
|
+
const isExplorationTool = EXPLORATION_TOOLS.has(toolName.toLowerCase());
|
|
17703
|
+
if (isExplorationTool) {
|
|
17704
|
+
return {
|
|
17705
|
+
fingerprint: strictFingerprint,
|
|
17706
|
+
repeatCount: strictRepeatCount,
|
|
17707
|
+
maxRepeat,
|
|
17708
|
+
errorClass,
|
|
17709
|
+
triggered: strictTriggered,
|
|
17710
|
+
tracked: true
|
|
17711
|
+
};
|
|
17712
|
+
}
|
|
17701
17713
|
const coarseRepeatCount = (coarseCounts.get(coarseFingerprint) ?? 0) + 1;
|
|
17702
17714
|
coarseCounts.set(coarseFingerprint, coarseRepeatCount);
|
|
17703
|
-
const strictTriggered = strictRepeatCount > maxRepeat;
|
|
17704
17715
|
const coarseTriggered = coarseRepeatCount > coarseMaxRepeat;
|
|
17705
17716
|
const preferCoarseFingerprint = coarseTriggered && !strictTriggered;
|
|
17706
17717
|
return {
|
|
@@ -17791,7 +17802,7 @@ function containsAny(text, patterns) {
|
|
|
17791
17802
|
function isRecord4(value) {
|
|
17792
17803
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17793
17804
|
}
|
|
17794
|
-
var UNKNOWN_AS_SUCCESS_TOOLS, COARSE_LIMIT_MULTIPLIER = 3;
|
|
17805
|
+
var UNKNOWN_AS_SUCCESS_TOOLS, EXPLORATION_TOOLS, COARSE_LIMIT_MULTIPLIER = 3;
|
|
17795
17806
|
var init_tool_loop_guard = __esm(() => {
|
|
17796
17807
|
UNKNOWN_AS_SUCCESS_TOOLS = new Set([
|
|
17797
17808
|
"bash",
|
|
@@ -17803,9 +17814,19 @@ var init_tool_loop_guard = __esm(() => {
|
|
|
17803
17814
|
"ls",
|
|
17804
17815
|
"glob",
|
|
17805
17816
|
"stat",
|
|
17806
|
-
"webfetch",
|
|
17807
17817
|
"mkdir",
|
|
17808
|
-
"rm"
|
|
17818
|
+
"rm",
|
|
17819
|
+
"webfetch",
|
|
17820
|
+
"semsearch",
|
|
17821
|
+
"readlints"
|
|
17822
|
+
]);
|
|
17823
|
+
EXPLORATION_TOOLS = new Set([
|
|
17824
|
+
"read",
|
|
17825
|
+
"grep",
|
|
17826
|
+
"glob",
|
|
17827
|
+
"ls",
|
|
17828
|
+
"stat",
|
|
17829
|
+
"semsearch"
|
|
17809
17830
|
]);
|
|
17810
17831
|
});
|
|
17811
17832
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rama_nigg/open-cursor",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.6",
|
|
4
4
|
"description": "No prompt limits. No broken streams. Full thinking + tool support. Your Cursor subscription, properly integrated.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/plugin-entry.js",
|
|
@@ -10,6 +10,7 @@ type ToolLoopErrorClass =
|
|
|
10
10
|
| "unknown";
|
|
11
11
|
|
|
12
12
|
const UNKNOWN_AS_SUCCESS_TOOLS = new Set([
|
|
13
|
+
// Core filesystem tools
|
|
13
14
|
"bash",
|
|
14
15
|
"shell",
|
|
15
16
|
"read",
|
|
@@ -19,9 +20,27 @@ const UNKNOWN_AS_SUCCESS_TOOLS = new Set([
|
|
|
19
20
|
"ls",
|
|
20
21
|
"glob",
|
|
21
22
|
"stat",
|
|
22
|
-
"webfetch",
|
|
23
23
|
"mkdir",
|
|
24
24
|
"rm",
|
|
25
|
+
// Web/network tools
|
|
26
|
+
"webfetch",
|
|
27
|
+
// cursor-agent specific tools (passthrough, but should not trigger loop guard)
|
|
28
|
+
// Discovered via tests/experiments/ harness - see docs/cursor-agent-tools.md
|
|
29
|
+
"semsearch", // semantic code search
|
|
30
|
+
"readlints", // lint/diagnostic reader
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
// Exploratory tools that commonly iterate over many files/patterns.
|
|
34
|
+
// These are exempt from COARSE fingerprint tracking (tool|errorClass) to allow
|
|
35
|
+
// legitimate multi-file exploration. Strict fingerprints (tool|args|errorClass)
|
|
36
|
+
// still apply to catch identical repeated failures.
|
|
37
|
+
const EXPLORATION_TOOLS = new Set([
|
|
38
|
+
"read",
|
|
39
|
+
"grep",
|
|
40
|
+
"glob",
|
|
41
|
+
"ls",
|
|
42
|
+
"stat",
|
|
43
|
+
"semsearch",
|
|
25
44
|
]);
|
|
26
45
|
|
|
27
46
|
export interface ToolLoopGuardDecision {
|
|
@@ -125,6 +144,7 @@ export function createToolLoopGuard(
|
|
|
125
144
|
const coarseFingerprint = `${toolCall.function.name}|${errorClass}`;
|
|
126
145
|
|
|
127
146
|
return evaluateWithFingerprints(
|
|
147
|
+
toolCall.function.name,
|
|
128
148
|
errorClass,
|
|
129
149
|
strictFingerprint,
|
|
130
150
|
coarseFingerprint,
|
|
@@ -140,6 +160,7 @@ export function createToolLoopGuard(
|
|
|
140
160
|
const strictFingerprint = `${toolCall.function.name}|schema:${normalizedSignature}|validation`;
|
|
141
161
|
const coarseFingerprint = `${toolCall.function.name}|validation`;
|
|
142
162
|
return evaluateWithFingerprints(
|
|
163
|
+
toolCall.function.name,
|
|
143
164
|
"validation",
|
|
144
165
|
strictFingerprint,
|
|
145
166
|
coarseFingerprint,
|
|
@@ -456,6 +477,7 @@ function normalizeValidationSignature(signature: string): string {
|
|
|
456
477
|
}
|
|
457
478
|
|
|
458
479
|
function evaluateWithFingerprints(
|
|
480
|
+
toolName: string,
|
|
459
481
|
errorClass: ToolLoopErrorClass,
|
|
460
482
|
strictFingerprint: string,
|
|
461
483
|
coarseFingerprint: string,
|
|
@@ -477,9 +499,22 @@ function evaluateWithFingerprints(
|
|
|
477
499
|
|
|
478
500
|
const strictRepeatCount = (strictCounts.get(strictFingerprint) ?? 0) + 1;
|
|
479
501
|
strictCounts.set(strictFingerprint, strictRepeatCount);
|
|
502
|
+
const strictTriggered = strictRepeatCount > maxRepeat;
|
|
503
|
+
|
|
504
|
+
const isExplorationTool = EXPLORATION_TOOLS.has(toolName.toLowerCase());
|
|
505
|
+
if (isExplorationTool) {
|
|
506
|
+
return {
|
|
507
|
+
fingerprint: strictFingerprint,
|
|
508
|
+
repeatCount: strictRepeatCount,
|
|
509
|
+
maxRepeat,
|
|
510
|
+
errorClass,
|
|
511
|
+
triggered: strictTriggered,
|
|
512
|
+
tracked: true,
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
|
|
480
516
|
const coarseRepeatCount = (coarseCounts.get(coarseFingerprint) ?? 0) + 1;
|
|
481
517
|
coarseCounts.set(coarseFingerprint, coarseRepeatCount);
|
|
482
|
-
const strictTriggered = strictRepeatCount > maxRepeat;
|
|
483
518
|
const coarseTriggered = coarseRepeatCount > coarseMaxRepeat;
|
|
484
519
|
const preferCoarseFingerprint = coarseTriggered && !strictTriggered;
|
|
485
520
|
return {
|