open-agents-ai 0.22.3 → 0.23.1
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/dist/index.js +204 -55
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6961,20 +6961,45 @@ var init_desktop_click = __esm({
|
|
|
6961
6961
|
durationMs: performance.now() - start
|
|
6962
6962
|
};
|
|
6963
6963
|
}
|
|
6964
|
-
|
|
6965
|
-
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
|
|
6972
|
-
|
|
6973
|
-
|
|
6964
|
+
let points = [];
|
|
6965
|
+
let visionWorked = false;
|
|
6966
|
+
try {
|
|
6967
|
+
const { vl } = await import("moondream");
|
|
6968
|
+
const apiKey = process.env["MOONDREAM_API_KEY"];
|
|
6969
|
+
const endpoint = process.env["MOONDREAM_ENDPOINT"];
|
|
6970
|
+
let client;
|
|
6971
|
+
if (apiKey) {
|
|
6972
|
+
client = new vl({ apiKey });
|
|
6973
|
+
} else if (endpoint) {
|
|
6974
|
+
client = new vl({ endpoint });
|
|
6975
|
+
} else {
|
|
6976
|
+
client = new vl({ endpoint: "http://localhost:2020/v1" });
|
|
6977
|
+
}
|
|
6978
|
+
const imageBuffer = readFileSync11(screenshotPath);
|
|
6979
|
+
const pointResult = await client.point({ image: imageBuffer, object: target });
|
|
6980
|
+
points = pointResult.points ?? [];
|
|
6981
|
+
visionWorked = true;
|
|
6982
|
+
} catch {
|
|
6983
|
+
}
|
|
6984
|
+
if (!visionWorked) {
|
|
6985
|
+
const hints = [
|
|
6986
|
+
`(Moondream vision not available \u2014 cannot locate "${target}" on screen)`,
|
|
6987
|
+
`Screenshot saved: ${screenshotPath}`,
|
|
6988
|
+
`Screen: ${dims.width}x${dims.height}`,
|
|
6989
|
+
"",
|
|
6990
|
+
"Use shell commands to interact with the desktop instead:",
|
|
6991
|
+
" xdotool search --name 'pattern' \u2014 find windows by title",
|
|
6992
|
+
" xdotool key 'ctrl+s' \u2014 send keyboard shortcuts",
|
|
6993
|
+
" xdotool mousemove X Y click 1 \u2014 click at known coordinates",
|
|
6994
|
+
" wmctrl -a 'window title' \u2014 activate a window by name",
|
|
6995
|
+
" xdg-open <url> \u2014 open a URL in the default browser"
|
|
6996
|
+
];
|
|
6997
|
+
return {
|
|
6998
|
+
success: true,
|
|
6999
|
+
output: hints.join("\n"),
|
|
7000
|
+
durationMs: performance.now() - start
|
|
7001
|
+
};
|
|
6974
7002
|
}
|
|
6975
|
-
const imageBuffer = readFileSync11(screenshotPath);
|
|
6976
|
-
const pointResult = await client.point({ image: imageBuffer, object: target });
|
|
6977
|
-
const points = pointResult.points ?? [];
|
|
6978
7003
|
if (points.length === 0) {
|
|
6979
7004
|
return {
|
|
6980
7005
|
success: false,
|
|
@@ -7066,37 +7091,62 @@ Screenshot: ${screenshotPath}`,
|
|
|
7066
7091
|
captureScreenshot(screenshotPath);
|
|
7067
7092
|
const dims = getImageDimensions2(screenshotPath);
|
|
7068
7093
|
const imageBuffer = readFileSync11(screenshotPath);
|
|
7069
|
-
const { vl } = await import("moondream");
|
|
7070
|
-
const apiKey = process.env["MOONDREAM_API_KEY"];
|
|
7071
|
-
const endpoint = process.env["MOONDREAM_ENDPOINT"];
|
|
7072
|
-
let client;
|
|
7073
|
-
if (apiKey) {
|
|
7074
|
-
client = new vl({ apiKey });
|
|
7075
|
-
} else if (endpoint) {
|
|
7076
|
-
client = new vl({ endpoint });
|
|
7077
|
-
} else {
|
|
7078
|
-
client = new vl({ endpoint: "http://localhost:2020/v1" });
|
|
7079
|
-
}
|
|
7080
7094
|
const parts = [];
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
const
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7095
|
+
let visionWorked = false;
|
|
7096
|
+
try {
|
|
7097
|
+
const { vl } = await import("moondream");
|
|
7098
|
+
const apiKey = process.env["MOONDREAM_API_KEY"];
|
|
7099
|
+
const endpoint = process.env["MOONDREAM_ENDPOINT"];
|
|
7100
|
+
let client;
|
|
7101
|
+
if (apiKey) {
|
|
7102
|
+
client = new vl({ apiKey });
|
|
7103
|
+
} else if (endpoint) {
|
|
7104
|
+
client = new vl({ endpoint });
|
|
7105
|
+
} else {
|
|
7106
|
+
client = new vl({ endpoint: "http://localhost:2020/v1" });
|
|
7107
|
+
}
|
|
7108
|
+
if (question) {
|
|
7109
|
+
const result = await client.query({ image: imageBuffer, question });
|
|
7110
|
+
const answer = typeof result.answer === "string" ? result.answer : "(streaming not supported)";
|
|
7111
|
+
parts.push(`Q: ${question}`);
|
|
7112
|
+
parts.push(`A: ${answer}`);
|
|
7113
|
+
} else {
|
|
7114
|
+
const result = await client.caption({ image: imageBuffer, length });
|
|
7115
|
+
const caption = typeof result.caption === "string" ? result.caption : "(streaming not supported)";
|
|
7116
|
+
parts.push(`Desktop description:
|
|
7090
7117
|
${caption}`);
|
|
7118
|
+
}
|
|
7119
|
+
visionWorked = true;
|
|
7120
|
+
} catch {
|
|
7121
|
+
}
|
|
7122
|
+
if (!visionWorked) {
|
|
7123
|
+
let ocrText = "";
|
|
7124
|
+
try {
|
|
7125
|
+
ocrText = execSync11(`tesseract ${JSON.stringify(screenshotPath)} stdout 2>/dev/null`, {
|
|
7126
|
+
encoding: "utf8",
|
|
7127
|
+
timeout: 15e3
|
|
7128
|
+
}).trim();
|
|
7129
|
+
} catch {
|
|
7130
|
+
}
|
|
7131
|
+
if (ocrText) {
|
|
7132
|
+
parts.push("(Moondream vision not available \u2014 using OCR text extraction)");
|
|
7133
|
+
parts.push(`
|
|
7134
|
+
Visible text on screen:
|
|
7135
|
+
${ocrText}`);
|
|
7136
|
+
} else {
|
|
7137
|
+
parts.push("(Moondream vision not available, OCR failed)");
|
|
7138
|
+
parts.push("Screenshot captured but cannot describe contents.");
|
|
7139
|
+
parts.push("Use shell commands to check window state instead:");
|
|
7140
|
+
parts.push(" xdotool getactivewindow getwindowname \u2014 get active window title");
|
|
7141
|
+
parts.push(" wmctrl -l \u2014 list all open windows");
|
|
7142
|
+
parts.push(" xdg-open <url> \u2014 open a URL in the default browser");
|
|
7143
|
+
}
|
|
7091
7144
|
}
|
|
7092
7145
|
if (dims) {
|
|
7093
7146
|
parts.push(`
|
|
7094
7147
|
Screen: ${dims.width}x${dims.height}`);
|
|
7095
7148
|
}
|
|
7096
7149
|
parts.push(`Screenshot: ${screenshotPath}`);
|
|
7097
|
-
const base64 = imageBuffer.toString("base64");
|
|
7098
|
-
parts.push(`
|
|
7099
|
-
[IMAGE_BASE64:image/png:${base64}]`);
|
|
7100
7150
|
return {
|
|
7101
7151
|
success: true,
|
|
7102
7152
|
output: parts.join("\n"),
|
|
@@ -9851,7 +9901,17 @@ var init_ralphLoop = __esm({
|
|
|
9851
9901
|
});
|
|
9852
9902
|
|
|
9853
9903
|
// packages/orchestrator/dist/agenticRunner.js
|
|
9854
|
-
|
|
9904
|
+
function getSystemPromptForTier(tier) {
|
|
9905
|
+
switch (tier) {
|
|
9906
|
+
case "small":
|
|
9907
|
+
return SYSTEM_PROMPT_SMALL;
|
|
9908
|
+
case "medium":
|
|
9909
|
+
return SYSTEM_PROMPT_MEDIUM;
|
|
9910
|
+
default:
|
|
9911
|
+
return SYSTEM_PROMPT;
|
|
9912
|
+
}
|
|
9913
|
+
}
|
|
9914
|
+
var SYSTEM_PROMPT, SYSTEM_PROMPT_MEDIUM, SYSTEM_PROMPT_SMALL, AgenticRunner, OllamaAgenticBackend;
|
|
9855
9915
|
var init_agenticRunner = __esm({
|
|
9856
9916
|
"packages/orchestrator/dist/agenticRunner.js"() {
|
|
9857
9917
|
"use strict";
|
|
@@ -10051,6 +10111,63 @@ If you notice you're performing the SAME multi-step sequence for the 3rd time or
|
|
|
10051
10111
|
- batch_edit to apply multiple edits across files in one call (reduces turns)
|
|
10052
10112
|
- Focus on error messages in shell output \u2014 skip verbose build logs
|
|
10053
10113
|
- Don't read files you don't need to modify`;
|
|
10114
|
+
SYSTEM_PROMPT_MEDIUM = `You are Open Agent, an AI coding agent with access to the local machine. You can read/write files, execute shell commands, search the web, and interact with any software. You solve tasks by using tools iteratively until complete.
|
|
10115
|
+
|
|
10116
|
+
## NEVER REFUSE \u2014 ALWAYS ATTEMPT
|
|
10117
|
+
|
|
10118
|
+
NEVER say "I can't do that". ALWAYS attempt the task using your tools. If a tool fails, try a different approach.
|
|
10119
|
+
|
|
10120
|
+
## Tools
|
|
10121
|
+
|
|
10122
|
+
- file_read: Read file contents (always read before editing)
|
|
10123
|
+
- file_write: Create or overwrite a file
|
|
10124
|
+
- file_edit: Precise string replacement (preferred over rewriting). old_string must be unique.
|
|
10125
|
+
- file_patch: Edit specific line ranges in large files
|
|
10126
|
+
- find_files: Find files by glob pattern
|
|
10127
|
+
- grep_search: Search file contents with regex
|
|
10128
|
+
- shell: Execute any shell command (tests, builds, git, npm, etc.)
|
|
10129
|
+
- list_directory: List files in a directory
|
|
10130
|
+
- web_search: Search the web
|
|
10131
|
+
- web_fetch: Fetch a web page's text
|
|
10132
|
+
- memory_read / memory_write: Persistent memory across sessions
|
|
10133
|
+
- task_complete: Signal task completion
|
|
10134
|
+
- batch_edit: Multiple edits across files in one call
|
|
10135
|
+
- skill_list / skill_execute: Discover and load specialized skills (use on-demand)
|
|
10136
|
+
|
|
10137
|
+
## Workflow
|
|
10138
|
+
|
|
10139
|
+
1. EXPLORE: Use find_files, grep_search, file_read to understand the codebase
|
|
10140
|
+
2. IMPLEMENT: Make changes with file_edit (preferred) or file_write
|
|
10141
|
+
3. VALIDATE: Run tests/build with shell. Read FULL output.
|
|
10142
|
+
4. FIX: If validation fails, fix the specific issue and re-validate
|
|
10143
|
+
5. ITERATE: Repeat until all tests pass. Do NOT give up.
|
|
10144
|
+
6. COMPLETE: Call task_complete when done
|
|
10145
|
+
|
|
10146
|
+
## Rules
|
|
10147
|
+
|
|
10148
|
+
- ALWAYS read a file before modifying it
|
|
10149
|
+
- ALWAYS run validation after changes
|
|
10150
|
+
- If tests fail, read the FULL error. Fix the exact issue.
|
|
10151
|
+
- Do NOT give up after failure. Iterate until it passes.
|
|
10152
|
+
- Use file_edit for small changes, not full file rewrites
|
|
10153
|
+
- You MUST call task_complete when done
|
|
10154
|
+
- Do NOT output long explanations. Focus on tool calls.`;
|
|
10155
|
+
SYSTEM_PROMPT_SMALL = `You are a coding agent. You MUST call tools in EVERY response. NEVER reply with only text.
|
|
10156
|
+
|
|
10157
|
+
Tools: file_read, file_write, file_edit, shell, task_complete, find_files, grep_search, web_search, web_fetch
|
|
10158
|
+
|
|
10159
|
+
Steps:
|
|
10160
|
+
1. file_read the source files AND test files
|
|
10161
|
+
2. file_edit or file_write to make changes
|
|
10162
|
+
3. shell to run tests (npm test, etc.)
|
|
10163
|
+
4. If tests fail: read error, fix, retest
|
|
10164
|
+
5. task_complete when tests pass
|
|
10165
|
+
|
|
10166
|
+
Rules:
|
|
10167
|
+
- ALWAYS call tools. NEVER just write text.
|
|
10168
|
+
- Read files before editing them.
|
|
10169
|
+
- Run tests after every change.
|
|
10170
|
+
- Call task_complete when done.`;
|
|
10054
10171
|
AgenticRunner = class {
|
|
10055
10172
|
backend;
|
|
10056
10173
|
tools = /* @__PURE__ */ new Map();
|
|
@@ -10073,7 +10190,8 @@ If you notice you're performing the SAME multi-step sequence for the 3rd time or
|
|
|
10073
10190
|
dynamicContext: options?.dynamicContext ?? "",
|
|
10074
10191
|
streamEnabled: options?.streamEnabled ?? false,
|
|
10075
10192
|
bruteForce: options?.bruteForce ?? true,
|
|
10076
|
-
bruteForceMaxCycles: options?.bruteForceMaxCycles ?? 100
|
|
10193
|
+
bruteForceMaxCycles: options?.bruteForceMaxCycles ?? 100,
|
|
10194
|
+
modelTier: options?.modelTier ?? "large"
|
|
10077
10195
|
};
|
|
10078
10196
|
}
|
|
10079
10197
|
/** Register a tool for the agent to use */
|
|
@@ -10151,9 +10269,10 @@ Respond with your assessment, then take action. Do NOT just say you'll continue
|
|
|
10151
10269
|
const toolCallLog = [];
|
|
10152
10270
|
this.aborted = false;
|
|
10153
10271
|
this.pendingUserMessages.length = 0;
|
|
10154
|
-
const
|
|
10272
|
+
const basePrompt = getSystemPromptForTier(this.options.modelTier);
|
|
10273
|
+
const systemPrompt = this.options.dynamicContext ? `${basePrompt}
|
|
10155
10274
|
|
|
10156
|
-
${this.options.dynamicContext}` :
|
|
10275
|
+
${this.options.dynamicContext}` : basePrompt;
|
|
10157
10276
|
const messages = [
|
|
10158
10277
|
{ role: "system", content: systemPrompt },
|
|
10159
10278
|
{ role: "user", content: context ? `${context}
|
|
@@ -15147,6 +15266,21 @@ import { existsSync as existsSync16, readFileSync as readFileSync13, readdirSync
|
|
|
15147
15266
|
import { join as join23, basename as basename6 } from "node:path";
|
|
15148
15267
|
import { execSync as execSync14 } from "node:child_process";
|
|
15149
15268
|
import { homedir as homedir9, platform, release } from "node:os";
|
|
15269
|
+
function getModelTier(modelName) {
|
|
15270
|
+
const m = modelName.toLowerCase();
|
|
15271
|
+
const sizeMatch = m.match(/\b(\d+)b\b/);
|
|
15272
|
+
if (sizeMatch) {
|
|
15273
|
+
const size = parseInt(sizeMatch[1], 10);
|
|
15274
|
+
if (size >= 30)
|
|
15275
|
+
return "large";
|
|
15276
|
+
if (size >= 8)
|
|
15277
|
+
return "medium";
|
|
15278
|
+
return "small";
|
|
15279
|
+
}
|
|
15280
|
+
if (/\b(small|mini|nano|tiny)\b/.test(m))
|
|
15281
|
+
return "small";
|
|
15282
|
+
return "large";
|
|
15283
|
+
}
|
|
15150
15284
|
function loadProjectFiles(repoRoot) {
|
|
15151
15285
|
const discovered = discoverContextFiles(repoRoot);
|
|
15152
15286
|
if (discovered.length === 0)
|
|
@@ -15361,7 +15495,7 @@ function buildProjectContext(repoRoot, stores) {
|
|
|
15361
15495
|
skillsSummary: buildSkillsSummary(discoverSkills(repoRoot))
|
|
15362
15496
|
};
|
|
15363
15497
|
}
|
|
15364
|
-
function formatContextForPrompt(ctx) {
|
|
15498
|
+
function formatContextForPrompt(ctx, modelTier = "large") {
|
|
15365
15499
|
const sections = [];
|
|
15366
15500
|
if (ctx.environment) {
|
|
15367
15501
|
sections.push(`## Environment
|
|
@@ -15374,9 +15508,17 @@ ${ctx.environment}`);
|
|
|
15374
15508
|
${ctx.gitInfo}`);
|
|
15375
15509
|
}
|
|
15376
15510
|
if (ctx.projectMap) {
|
|
15377
|
-
|
|
15511
|
+
if (modelTier === "small") {
|
|
15512
|
+
} else if (modelTier === "medium" && ctx.projectMap.length > 2e3) {
|
|
15513
|
+
sections.push(`## Project Map (truncated)
|
|
15514
|
+
|
|
15515
|
+
${ctx.projectMap.slice(0, 2e3)}
|
|
15516
|
+
...(use find_files/list_directory for full listing)`);
|
|
15517
|
+
} else {
|
|
15518
|
+
sections.push(`## Project Map
|
|
15378
15519
|
|
|
15379
15520
|
${ctx.projectMap}`);
|
|
15521
|
+
}
|
|
15380
15522
|
}
|
|
15381
15523
|
if (ctx.projectInstructions) {
|
|
15382
15524
|
sections.push(ctx.projectInstructions);
|
|
@@ -15388,17 +15530,19 @@ ${ctx.memoryContext}
|
|
|
15388
15530
|
|
|
15389
15531
|
Use this context to avoid re-learning known patterns. Update with memory_write if you discover new insights.`);
|
|
15390
15532
|
}
|
|
15391
|
-
if (
|
|
15392
|
-
|
|
15533
|
+
if (modelTier !== "small") {
|
|
15534
|
+
if (ctx.sessionHistory) {
|
|
15535
|
+
sections.push(`## Session History
|
|
15393
15536
|
|
|
15394
15537
|
${ctx.sessionHistory}`);
|
|
15395
|
-
|
|
15396
|
-
|
|
15397
|
-
|
|
15538
|
+
}
|
|
15539
|
+
if (ctx.taskMemories) {
|
|
15540
|
+
sections.push(`## Cross-Session Task Memory
|
|
15398
15541
|
|
|
15399
15542
|
${ctx.taskMemories}
|
|
15400
15543
|
|
|
15401
15544
|
Use this history to avoid re-doing completed work and to learn from past approaches.`);
|
|
15545
|
+
}
|
|
15402
15546
|
}
|
|
15403
15547
|
if (ctx.failurePatterns) {
|
|
15404
15548
|
sections.push(`## Known Failure Patterns
|
|
@@ -15407,14 +15551,14 @@ ${ctx.failurePatterns}
|
|
|
15407
15551
|
|
|
15408
15552
|
Avoid approaches that led to these failures. If you encounter these errors, try a different strategy.`);
|
|
15409
15553
|
}
|
|
15410
|
-
if (ctx.patternSuggestions) {
|
|
15554
|
+
if (modelTier === "large" && ctx.patternSuggestions) {
|
|
15411
15555
|
sections.push(`## Tool Creation Suggestions
|
|
15412
15556
|
|
|
15413
15557
|
${ctx.patternSuggestions}
|
|
15414
15558
|
|
|
15415
15559
|
These patterns have been repeated 3+ times. Consider using create_tool to automate them.`);
|
|
15416
15560
|
}
|
|
15417
|
-
if (ctx.skillsSummary) {
|
|
15561
|
+
if (modelTier === "large" && ctx.skillsSummary) {
|
|
15418
15562
|
sections.push(ctx.skillsSummary);
|
|
15419
15563
|
}
|
|
15420
15564
|
return sections.join("\n\n");
|
|
@@ -17813,8 +17957,9 @@ ${result.summary}`;
|
|
|
17813
17957
|
/** Run a dream agent with appropriate tools */
|
|
17814
17958
|
async runDreamAgent(prompt, toolMode, onEvent) {
|
|
17815
17959
|
const backend = new OllamaAgenticBackend(this.config.backendUrl, this.config.model, this.config.apiKey);
|
|
17960
|
+
const modelTier = getModelTier(this.config.model);
|
|
17816
17961
|
const projectCtx = buildProjectContext(this.repoRoot);
|
|
17817
|
-
const dynamicContext = formatContextForPrompt(projectCtx);
|
|
17962
|
+
const dynamicContext = formatContextForPrompt(projectCtx, modelTier);
|
|
17818
17963
|
const runner = new AgenticRunner(backend, {
|
|
17819
17964
|
maxTurns: 20,
|
|
17820
17965
|
maxTokens: 16384,
|
|
@@ -17822,8 +17967,9 @@ ${result.summary}`;
|
|
|
17822
17967
|
// Slightly creative temperature for dreaming
|
|
17823
17968
|
requestTimeoutMs: this.config.timeoutMs,
|
|
17824
17969
|
taskTimeoutMs: this.config.timeoutMs * 3,
|
|
17825
|
-
compactionThreshold: 4e4,
|
|
17826
|
-
dynamicContext
|
|
17970
|
+
compactionThreshold: modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4,
|
|
17971
|
+
dynamicContext,
|
|
17972
|
+
modelTier
|
|
17827
17973
|
});
|
|
17828
17974
|
const tools = this.buildDreamTools(toolMode);
|
|
17829
17975
|
runner.registerTools(tools);
|
|
@@ -18769,12 +18915,14 @@ Use task_status("${taskId}") or task_output("${taskId}") to check progress.`
|
|
|
18769
18915
|
};
|
|
18770
18916
|
}
|
|
18771
18917
|
function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce, statusBar, sudoCallback, costTracker, onComplete, taskType) {
|
|
18918
|
+
const modelTier = getModelTier(config.model);
|
|
18772
18919
|
const projectCtx = buildProjectContext(repoRoot, taskStores?.contextStores);
|
|
18773
|
-
let dynamicContext = formatContextForPrompt(projectCtx);
|
|
18774
|
-
if (taskType) {
|
|
18920
|
+
let dynamicContext = formatContextForPrompt(projectCtx, modelTier);
|
|
18921
|
+
if (taskType && modelTier !== "small") {
|
|
18775
18922
|
dynamicContext += "\n\n" + buildTaskContext(taskType);
|
|
18776
18923
|
}
|
|
18777
18924
|
const backend = new OllamaAgenticBackend(config.backendUrl, config.model, config.apiKey);
|
|
18925
|
+
const compactionThreshold = modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4;
|
|
18778
18926
|
const runner = new AgenticRunner(backend, {
|
|
18779
18927
|
maxTurns: 60,
|
|
18780
18928
|
maxTokens: 16384,
|
|
@@ -18782,8 +18930,9 @@ function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce
|
|
|
18782
18930
|
requestTimeoutMs: config.timeoutMs,
|
|
18783
18931
|
taskTimeoutMs: 36e5,
|
|
18784
18932
|
// 60 minutes — never give up prematurely
|
|
18785
|
-
compactionThreshold
|
|
18933
|
+
compactionThreshold,
|
|
18786
18934
|
dynamicContext,
|
|
18935
|
+
modelTier,
|
|
18787
18936
|
streamEnabled: stream?.enabled ?? false,
|
|
18788
18937
|
bruteForce: bruteForce ?? true,
|
|
18789
18938
|
bruteForceMaxCycles: 100
|
package/package.json
CHANGED