@rama_nigg/open-cursor 2.3.6 → 2.3.9
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 +1 -1
- package/dist/index.js +9 -5
- package/dist/plugin-entry.js +9 -5
- package/package.json +1 -1
- package/src/provider/tool-loop-guard.ts +16 -3
package/README.md
CHANGED
|
@@ -154,7 +154,7 @@ flowchart TB
|
|
|
154
154
|
Default mode: `CURSOR_ACP_TOOL_LOOP_MODE=opencode`. Legacy `proxy-exec` still available. Details: [docs/architecture/runtime-tool-loop.md](docs/architecture/runtime-tool-loop.md).
|
|
155
155
|
|
|
156
156
|
## Alternatives
|
|
157
|
-
|
|
157
|
+
THERE is currently not a single perfect plugin for cursor in opencode, my advice is stick with what is the LEAST worst option for you.
|
|
158
158
|
| | open-cursor | [yet-another-opencode-cursor-auth](https://github.com/Yukaii/yet-another-opencode-cursor-auth) | [opencode-cursor-auth](https://github.com/POSO-PocketSolutions/opencode-cursor-auth) | [cursor-opencode-auth](https://github.com/R44VC0RP/cursor-opencode-auth) |
|
|
159
159
|
| ----------------- | :------------------------: | :--------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------: | :----------------------------------------------------------------------: |
|
|
160
160
|
| **Architecture** | HTTP proxy via cursor-agent | Direct Connect-RPC | HTTP proxy via cursor-agent | Direct Connect-RPC/protobuf |
|
package/dist/index.js
CHANGED
|
@@ -17431,18 +17431,20 @@ function createToolLoopGuard(messages, maxRepeat) {
|
|
|
17431
17431
|
const successFingerprint = `${toolCall.function.name}|values:${valueSignature}|success`;
|
|
17432
17432
|
const repeatCount = (counts.get(successFingerprint) ?? 0) + 1;
|
|
17433
17433
|
counts.set(successFingerprint, repeatCount);
|
|
17434
|
+
const isExplorationTool = EXPLORATION_TOOLS.has(toolCall.function.name.toLowerCase());
|
|
17435
|
+
const effectiveMaxRepeat = isExplorationTool ? maxRepeat * EXPLORATION_LIMIT_MULTIPLIER : maxRepeat;
|
|
17434
17436
|
const coarseSuccessFingerprint = deriveSuccessCoarseFingerprint(toolCall.function.name, toolCall.function.arguments);
|
|
17435
17437
|
const coarseRepeatCount = coarseSuccessFingerprint ? (coarseCounts.get(coarseSuccessFingerprint) ?? 0) + 1 : 0;
|
|
17436
17438
|
if (coarseSuccessFingerprint) {
|
|
17437
17439
|
coarseCounts.set(coarseSuccessFingerprint, coarseRepeatCount);
|
|
17438
17440
|
}
|
|
17439
|
-
const coarseTriggered = coarseSuccessFingerprint ? coarseRepeatCount >
|
|
17441
|
+
const coarseTriggered = coarseSuccessFingerprint ? coarseRepeatCount > effectiveMaxRepeat : false;
|
|
17440
17442
|
return {
|
|
17441
17443
|
fingerprint: coarseTriggered ? coarseSuccessFingerprint : successFingerprint,
|
|
17442
17444
|
repeatCount: coarseTriggered ? coarseRepeatCount : repeatCount,
|
|
17443
|
-
maxRepeat,
|
|
17445
|
+
maxRepeat: effectiveMaxRepeat,
|
|
17444
17446
|
errorClass,
|
|
17445
|
-
triggered: repeatCount >
|
|
17447
|
+
triggered: repeatCount > effectiveMaxRepeat || coarseTriggered,
|
|
17446
17448
|
tracked: true
|
|
17447
17449
|
};
|
|
17448
17450
|
}
|
|
@@ -17802,7 +17804,7 @@ function containsAny(text, patterns) {
|
|
|
17802
17804
|
function isRecord4(value) {
|
|
17803
17805
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17804
17806
|
}
|
|
17805
|
-
var UNKNOWN_AS_SUCCESS_TOOLS, EXPLORATION_TOOLS, COARSE_LIMIT_MULTIPLIER = 3;
|
|
17807
|
+
var UNKNOWN_AS_SUCCESS_TOOLS, EXPLORATION_TOOLS, COARSE_LIMIT_MULTIPLIER = 3, EXPLORATION_LIMIT_MULTIPLIER = 5;
|
|
17806
17808
|
var init_tool_loop_guard = __esm(() => {
|
|
17807
17809
|
UNKNOWN_AS_SUCCESS_TOOLS = new Set([
|
|
17808
17810
|
"bash",
|
|
@@ -17826,7 +17828,9 @@ var init_tool_loop_guard = __esm(() => {
|
|
|
17826
17828
|
"glob",
|
|
17827
17829
|
"ls",
|
|
17828
17830
|
"stat",
|
|
17829
|
-
"semsearch"
|
|
17831
|
+
"semsearch",
|
|
17832
|
+
"bash",
|
|
17833
|
+
"shell"
|
|
17830
17834
|
]);
|
|
17831
17835
|
});
|
|
17832
17836
|
|
package/dist/plugin-entry.js
CHANGED
|
@@ -17431,18 +17431,20 @@ function createToolLoopGuard(messages, maxRepeat) {
|
|
|
17431
17431
|
const successFingerprint = `${toolCall.function.name}|values:${valueSignature}|success`;
|
|
17432
17432
|
const repeatCount = (counts.get(successFingerprint) ?? 0) + 1;
|
|
17433
17433
|
counts.set(successFingerprint, repeatCount);
|
|
17434
|
+
const isExplorationTool = EXPLORATION_TOOLS.has(toolCall.function.name.toLowerCase());
|
|
17435
|
+
const effectiveMaxRepeat = isExplorationTool ? maxRepeat * EXPLORATION_LIMIT_MULTIPLIER : maxRepeat;
|
|
17434
17436
|
const coarseSuccessFingerprint = deriveSuccessCoarseFingerprint(toolCall.function.name, toolCall.function.arguments);
|
|
17435
17437
|
const coarseRepeatCount = coarseSuccessFingerprint ? (coarseCounts.get(coarseSuccessFingerprint) ?? 0) + 1 : 0;
|
|
17436
17438
|
if (coarseSuccessFingerprint) {
|
|
17437
17439
|
coarseCounts.set(coarseSuccessFingerprint, coarseRepeatCount);
|
|
17438
17440
|
}
|
|
17439
|
-
const coarseTriggered = coarseSuccessFingerprint ? coarseRepeatCount >
|
|
17441
|
+
const coarseTriggered = coarseSuccessFingerprint ? coarseRepeatCount > effectiveMaxRepeat : false;
|
|
17440
17442
|
return {
|
|
17441
17443
|
fingerprint: coarseTriggered ? coarseSuccessFingerprint : successFingerprint,
|
|
17442
17444
|
repeatCount: coarseTriggered ? coarseRepeatCount : repeatCount,
|
|
17443
|
-
maxRepeat,
|
|
17445
|
+
maxRepeat: effectiveMaxRepeat,
|
|
17444
17446
|
errorClass,
|
|
17445
|
-
triggered: repeatCount >
|
|
17447
|
+
triggered: repeatCount > effectiveMaxRepeat || coarseTriggered,
|
|
17446
17448
|
tracked: true
|
|
17447
17449
|
};
|
|
17448
17450
|
}
|
|
@@ -17802,7 +17804,7 @@ function containsAny(text, patterns) {
|
|
|
17802
17804
|
function isRecord4(value) {
|
|
17803
17805
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17804
17806
|
}
|
|
17805
|
-
var UNKNOWN_AS_SUCCESS_TOOLS, EXPLORATION_TOOLS, COARSE_LIMIT_MULTIPLIER = 3;
|
|
17807
|
+
var UNKNOWN_AS_SUCCESS_TOOLS, EXPLORATION_TOOLS, COARSE_LIMIT_MULTIPLIER = 3, EXPLORATION_LIMIT_MULTIPLIER = 5;
|
|
17806
17808
|
var init_tool_loop_guard = __esm(() => {
|
|
17807
17809
|
UNKNOWN_AS_SUCCESS_TOOLS = new Set([
|
|
17808
17810
|
"bash",
|
|
@@ -17826,7 +17828,9 @@ var init_tool_loop_guard = __esm(() => {
|
|
|
17826
17828
|
"glob",
|
|
17827
17829
|
"ls",
|
|
17828
17830
|
"stat",
|
|
17829
|
-
"semsearch"
|
|
17831
|
+
"semsearch",
|
|
17832
|
+
"bash",
|
|
17833
|
+
"shell"
|
|
17830
17834
|
]);
|
|
17831
17835
|
});
|
|
17832
17836
|
|
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.9",
|
|
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",
|
|
@@ -41,6 +41,8 @@ const EXPLORATION_TOOLS = new Set([
|
|
|
41
41
|
"ls",
|
|
42
42
|
"stat",
|
|
43
43
|
"semsearch",
|
|
44
|
+
"bash",
|
|
45
|
+
"shell",
|
|
44
46
|
]);
|
|
45
47
|
|
|
46
48
|
export interface ToolLoopGuardDecision {
|
|
@@ -75,6 +77,7 @@ export function parseToolLoopMaxRepeat(
|
|
|
75
77
|
// to allow legitimate exploration across different files/targets while still
|
|
76
78
|
// catching spray-and-pray patterns.
|
|
77
79
|
const COARSE_LIMIT_MULTIPLIER = 3;
|
|
80
|
+
const EXPLORATION_LIMIT_MULTIPLIER = 5;
|
|
78
81
|
|
|
79
82
|
export function createToolLoopGuard(
|
|
80
83
|
messages: Array<unknown>,
|
|
@@ -113,6 +116,16 @@ export function createToolLoopGuard(
|
|
|
113
116
|
const repeatCount = (counts.get(successFingerprint) ?? 0) + 1;
|
|
114
117
|
counts.set(successFingerprint, repeatCount);
|
|
115
118
|
|
|
119
|
+
// Exploration tools (read, grep, glob, etc.) get a higher limit because
|
|
120
|
+
// re-reading the same file across turns is legitimate behavior (verifying
|
|
121
|
+
// edits, checking state, etc.). Use 5x multiplier for these tools.
|
|
122
|
+
const isExplorationTool = EXPLORATION_TOOLS.has(
|
|
123
|
+
toolCall.function.name.toLowerCase(),
|
|
124
|
+
);
|
|
125
|
+
const effectiveMaxRepeat = isExplorationTool
|
|
126
|
+
? maxRepeat * EXPLORATION_LIMIT_MULTIPLIER
|
|
127
|
+
: maxRepeat;
|
|
128
|
+
|
|
116
129
|
// Some tools (notably edit/write) can get stuck in "successful" loops where
|
|
117
130
|
// the model keeps re-issuing the same operation with slightly different
|
|
118
131
|
// content (e.g. trailing newline differences). Track a coarse signature for
|
|
@@ -129,14 +142,14 @@ export function createToolLoopGuard(
|
|
|
129
142
|
coarseCounts.set(coarseSuccessFingerprint, coarseRepeatCount);
|
|
130
143
|
}
|
|
131
144
|
const coarseTriggered = coarseSuccessFingerprint
|
|
132
|
-
? coarseRepeatCount >
|
|
145
|
+
? coarseRepeatCount > effectiveMaxRepeat
|
|
133
146
|
: false;
|
|
134
147
|
return {
|
|
135
148
|
fingerprint: coarseTriggered ? coarseSuccessFingerprint! : successFingerprint,
|
|
136
149
|
repeatCount: coarseTriggered ? coarseRepeatCount : repeatCount,
|
|
137
|
-
maxRepeat,
|
|
150
|
+
maxRepeat: effectiveMaxRepeat,
|
|
138
151
|
errorClass,
|
|
139
|
-
triggered: repeatCount >
|
|
152
|
+
triggered: repeatCount > effectiveMaxRepeat || coarseTriggered,
|
|
140
153
|
tracked: true,
|
|
141
154
|
};
|
|
142
155
|
}
|