nothumanallowed 9.3.13 → 9.3.15
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/package.json +1 -1
- package/src/commands/ui.mjs +8 -5
- package/src/constants.mjs +1 -1
- package/src/services/tool-executor.mjs +20 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "9.3.
|
|
3
|
+
"version": "9.3.15",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents + 58 tools + browser automation + web search. Streaming chat, headless Chrome CDP, multi-conversation, export. Gmail, Calendar, Drive, GitHub, Notion, Slack. Zero-dependency CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/commands/ui.mjs
CHANGED
|
@@ -1210,13 +1210,16 @@ export async function cmdUI(args) {
|
|
|
1210
1210
|
sendSSE('tool', { action, status: 'error', error: 'No browser open' });
|
|
1211
1211
|
continue;
|
|
1212
1212
|
}
|
|
1213
|
+
// Scroll to top for best viewport
|
|
1214
|
+
await be.browserScroll({ direction: 'top' });
|
|
1215
|
+
await new Promise(r => setTimeout(r, 300));
|
|
1213
1216
|
const ssResult = await be.browserScreenshot({
|
|
1214
|
-
fullPage:
|
|
1215
|
-
format:
|
|
1216
|
-
quality:
|
|
1217
|
+
fullPage: false, // Always viewport
|
|
1218
|
+
format: 'jpeg',
|
|
1219
|
+
quality: 75,
|
|
1217
1220
|
});
|
|
1218
1221
|
if (!ssResult.error) {
|
|
1219
|
-
sendSSE('screenshot', { base64: ssResult.base64, format:
|
|
1222
|
+
sendSSE('screenshot', { base64: ssResult.base64, format: 'jpeg' });
|
|
1220
1223
|
toolResults.push({ action, result: `Screenshot captured (${Math.round(ssResult.size / 1024)}KB)` });
|
|
1221
1224
|
sendSSE('tool', { action, status: 'done', result: 'Screenshot captured' });
|
|
1222
1225
|
} else {
|
|
@@ -1236,7 +1239,7 @@ export async function cmdUI(args) {
|
|
|
1236
1239
|
try {
|
|
1237
1240
|
const be = await import('../services/browser-engine.mjs');
|
|
1238
1241
|
if (be.isBrowserRunning()) {
|
|
1239
|
-
const ssResult = await be.browserScreenshot({ fullPage:
|
|
1242
|
+
const ssResult = await be.browserScreenshot({ fullPage: false, format: 'jpeg', quality: 75 });
|
|
1240
1243
|
if (!ssResult.error) {
|
|
1241
1244
|
sendSSE('screenshot', { base64: ssResult.base64, format: 'png' });
|
|
1242
1245
|
}
|
package/src/constants.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url';
|
|
|
5
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = path.dirname(__filename);
|
|
7
7
|
|
|
8
|
-
export const VERSION = '9.3.
|
|
8
|
+
export const VERSION = '9.3.15';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
|
@@ -74,14 +74,16 @@ export const DESTRUCTIVE_ACTIONS = new Set([
|
|
|
74
74
|
*/
|
|
75
75
|
export const TOOL_DEFINITIONS = `
|
|
76
76
|
You have access to the following tools. When the user's message requires an action,
|
|
77
|
-
output
|
|
77
|
+
output one or more fenced JSON blocks:
|
|
78
78
|
|
|
79
79
|
\`\`\`json
|
|
80
80
|
{"action": "<tool_name>", "params": { ... }}
|
|
81
81
|
\`\`\`
|
|
82
82
|
|
|
83
|
-
You
|
|
84
|
-
|
|
83
|
+
You can include multiple JSON blocks in one response for sequential actions.
|
|
84
|
+
You may include conversational text BEFORE, BETWEEN, or AFTER JSON blocks.
|
|
85
|
+
If no action is needed, respond normally without any JSON block.
|
|
86
|
+
CRITICAL: Never output a JSON block as a "suggestion" or "let me try" — every JSON block WILL be executed immediately. Only output a JSON block when you are certain the action should be performed.
|
|
85
87
|
|
|
86
88
|
TOOLS:
|
|
87
89
|
|
|
@@ -287,10 +289,11 @@ TOOLS:
|
|
|
287
289
|
Use this when you need to interact with a page (click, type, screenshot) or when fetch_url fails on JS-rendered content.
|
|
288
290
|
WARNING: Do NOT use this to search the web — use web_search instead. Google/Bing block automated browsers with CAPTCHAs.
|
|
289
291
|
|
|
290
|
-
50. browser_screenshot(
|
|
291
|
-
Capture a screenshot of the current browser
|
|
292
|
-
|
|
293
|
-
|
|
292
|
+
50. browser_screenshot(saveTo?: string)
|
|
293
|
+
Capture a screenshot of the current browser viewport (what's visible on screen).
|
|
294
|
+
saveTo saves to a file path (e.g. "~/screenshot.png"). Returns base64-encoded image.
|
|
295
|
+
ALWAYS use viewport screenshots (the default). Do NOT pass fullPage=true — it produces oversized images.
|
|
296
|
+
Screenshots are automatically compressed as JPEG for efficiency.
|
|
294
297
|
|
|
295
298
|
51. browser_click(text?: string, selector?: string, x?: number, y?: number)
|
|
296
299
|
Click an element on the page by visible text, CSS selector, or x/y coordinates.
|
|
@@ -345,6 +348,7 @@ RULES:
|
|
|
345
348
|
- The user's timezone is {{TIMEZONE}}.
|
|
346
349
|
- CRITICAL: when creating calendar events, always use LOCAL time in format "YYYY-MM-DDTHH:MM:SS" WITHOUT any Z suffix or timezone offset.
|
|
347
350
|
- LANGUAGE: Respond in {{LANGUAGE}}. All conversational text, explanations, and descriptions must be in {{LANGUAGE}}. Tool names and JSON blocks remain in English.
|
|
351
|
+
- BROWSER TIP: When extracting data from a page, prefer browser_js with simple JavaScript over complex CSS selectors. Example: browser_js with code "document.body.innerText.slice(0, 3000)" to get all visible text, then parse it yourself. This is more reliable than guessing CSS selectors.
|
|
348
352
|
`.trim();
|
|
349
353
|
|
|
350
354
|
// ── Action Parser ────────────────────────────────────────────────────────────
|
|
@@ -1139,14 +1143,19 @@ export async function executeTool(action, params, config) {
|
|
|
1139
1143
|
const be = await import('./browser-engine.mjs');
|
|
1140
1144
|
if (!be.isBrowserRunning()) return 'No browser open. Use browser_open first.';
|
|
1141
1145
|
|
|
1146
|
+
// Scroll to top before screenshot so user sees the most important content
|
|
1147
|
+
await be.browserScroll({ direction: 'top' });
|
|
1148
|
+
await new Promise(r => setTimeout(r, 300));
|
|
1149
|
+
|
|
1142
1150
|
const saveTo = params.saveTo
|
|
1143
1151
|
? params.saveTo.replace(/^~/, os.homedir())
|
|
1144
1152
|
: null;
|
|
1145
1153
|
|
|
1154
|
+
// Always use JPEG for efficiency (smaller base64, faster rendering in web UI)
|
|
1146
1155
|
const result = await be.browserScreenshot({
|
|
1147
|
-
fullPage:
|
|
1148
|
-
format:
|
|
1149
|
-
quality:
|
|
1156
|
+
fullPage: false, // Always viewport — fullPage produces oversized images
|
|
1157
|
+
format: 'jpeg',
|
|
1158
|
+
quality: 75,
|
|
1150
1159
|
saveTo,
|
|
1151
1160
|
});
|
|
1152
1161
|
if (result.error) return `Screenshot error: ${result.message}`;
|
|
@@ -1326,7 +1335,7 @@ export async function executeTool(action, params, config) {
|
|
|
1326
1335
|
// Render by injecting HTML into current page via JS
|
|
1327
1336
|
await be.browserEval(`document.open();document.write(${JSON.stringify(fullHtml)});document.close();`);
|
|
1328
1337
|
await new Promise(r => setTimeout(r, 300));
|
|
1329
|
-
const ss = await be.browserScreenshot({ fullPage:
|
|
1338
|
+
const ss = await be.browserScreenshot({ fullPage: false, format: 'jpeg', quality: 75 });
|
|
1330
1339
|
if (!ss.error) {
|
|
1331
1340
|
return textResult + `\n\n[Screenshot of results captured (${Math.round(ss.size / 1024)}KB)]`;
|
|
1332
1341
|
}
|