nothumanallowed 14.1.41 → 14.1.42
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/constants.mjs +1 -1
- package/src/server/routes/webcraft.mjs +69 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "14.1.
|
|
3
|
+
"version": "14.1.42",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents, 80 tools, Studio (visual agentic workflows). Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, Alexandria E2E messaging, GitHub, Notion, Slack, voice chat, free AI (Liara), 28 languages. Zero-dependency CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
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 = '14.1.
|
|
8
|
+
export const VERSION = '14.1.42';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
|
@@ -19,7 +19,7 @@ import { createServer } from 'net';
|
|
|
19
19
|
import { promisify } from 'util';
|
|
20
20
|
import { sendJSON, sendError, parseBody, sendSSE } from '../index.mjs';
|
|
21
21
|
import { loadConfig } from '../../config.mjs';
|
|
22
|
-
import { callLLM, callLLMStream } from '../../services/llm.mjs';
|
|
22
|
+
import { callLLM, callLLMStream, fixQwen3BPE } from '../../services/llm.mjs';
|
|
23
23
|
import { NHA_DIR } from '../../constants.mjs';
|
|
24
24
|
|
|
25
25
|
const execAsync = promisify(exec);
|
|
@@ -443,11 +443,34 @@ RULES:
|
|
|
443
443
|
- After each tool use, continue explaining what you did
|
|
444
444
|
`;
|
|
445
445
|
|
|
446
|
+
// Load memory.md and skills.md for context
|
|
447
|
+
const ctxDir = SkillStore.dir(projectName);
|
|
448
|
+
let contextFiles = '';
|
|
449
|
+
try {
|
|
450
|
+
const memPath = path.join(ctxDir, 'memory.md');
|
|
451
|
+
const skillsPath = path.join(ctxDir, 'skills.md');
|
|
452
|
+
const providerPath = path.join(ctxDir, `${config.llm?.provider || 'nha'}.md`);
|
|
453
|
+
|
|
454
|
+
if (fs.existsSync(memPath)) {
|
|
455
|
+
const memContent = fs.readFileSync(memPath, 'utf-8');
|
|
456
|
+
contextFiles += `\n### MEMORY:\n${memContent}\n`;
|
|
457
|
+
}
|
|
458
|
+
if (fs.existsSync(skillsPath)) {
|
|
459
|
+
const skillsContent = fs.readFileSync(skillsPath, 'utf-8');
|
|
460
|
+
contextFiles += `\n### SKILLS:\n${skillsContent}\n`;
|
|
461
|
+
}
|
|
462
|
+
if (fs.existsSync(providerPath)) {
|
|
463
|
+
const providerContent = fs.readFileSync(providerPath, 'utf-8');
|
|
464
|
+
contextFiles += `\n### MODEL INFO:\n${providerContent}\n`;
|
|
465
|
+
}
|
|
466
|
+
} catch {}
|
|
467
|
+
|
|
446
468
|
const systemPrompt = [
|
|
447
469
|
`You are WebCraft Agent, an expert full-stack developer. Today is ${today}. Respond in ${language}.`,
|
|
448
470
|
`\n\n## PROJECT: ${projectName}`,
|
|
449
471
|
`\n## FILES:\n${fileIndex}`,
|
|
450
|
-
|
|
472
|
+
contextFiles,
|
|
473
|
+
skillCtx ? `\n\n## ADDITIONAL CONTEXT:\n${skillCtx}` : '',
|
|
451
474
|
attachments?.length ? `\n\n## ATTACHMENTS: ${attachments.map((a) => a.name).join(', ')}` : '',
|
|
452
475
|
`\n\n## CURRENT FILE CONTENTS:\n${fileContents}`,
|
|
453
476
|
`\n\n${toolSpec}`,
|
|
@@ -464,8 +487,10 @@ RULES:
|
|
|
464
487
|
|
|
465
488
|
await callLLMStream(config, systemPrompt, userContent, (token) => {
|
|
466
489
|
fullResponse += token;
|
|
490
|
+
// Apply BPE fix for better Italian text quality
|
|
491
|
+
const fixedToken = fixQwen3BPE(token);
|
|
467
492
|
// Suppress raw <tool> blocks from text stream — only emit visible text
|
|
468
|
-
const visibleToken =
|
|
493
|
+
const visibleToken = fixedToken.replace(/<tool>[\s\S]*?<\/tool>/g, '');
|
|
469
494
|
if (visibleToken) emit({ type: 'text', token: visibleToken });
|
|
470
495
|
}, { max_tokens: 8192 });
|
|
471
496
|
|
|
@@ -521,6 +546,17 @@ RULES:
|
|
|
521
546
|
}
|
|
522
547
|
}
|
|
523
548
|
|
|
549
|
+
// Log chat interaction to changes.log.md
|
|
550
|
+
if (hasChanges) {
|
|
551
|
+
try {
|
|
552
|
+
const ctxDir = SkillStore.dir(projectName);
|
|
553
|
+
const logFile = path.join(ctxDir, 'changes.log.md');
|
|
554
|
+
const timestamp = new Date().toISOString();
|
|
555
|
+
const logEntry = `\n## ${timestamp.slice(0, 16).replace('T', ' ')} — Chat modification\n- User: ${message.slice(0, 100)}${message.length > 100 ? '...' : ''}\n- Files modified: ${fullResponse.match(/<tool>[\s\S]*?"op":"(write|edit)"[\s\S]*?"path":"([^"]+)"[\s\S]*?<\/tool>/g)?.map(m => m.match(/"path":"([^"]+)"/)?.[1]).filter(Boolean).join(', ') || 'none'}\n`;
|
|
556
|
+
fs.writeFileSync(logFile, (fs.existsSync(logFile) ? fs.readFileSync(logFile, 'utf-8') : '') + logEntry, 'utf-8');
|
|
557
|
+
} catch {}
|
|
558
|
+
}
|
|
559
|
+
|
|
524
560
|
emit({ type: 'done', changed: hasChanges });
|
|
525
561
|
}
|
|
526
562
|
|
|
@@ -824,8 +860,37 @@ This approach ensures agents have the right context without being overwhelmed by
|
|
|
824
860
|
`;
|
|
825
861
|
fs.writeFileSync(skillsFile, skillsContent, 'utf-8');
|
|
826
862
|
}
|
|
863
|
+
// Initialize provider-specific file (liara.md, claude.md, etc.)
|
|
864
|
+
const config = loadConfig();
|
|
865
|
+
const provider = config.llm?.provider || 'nha';
|
|
866
|
+
const model = config.llm?.model || '';
|
|
867
|
+
const providerFile = path.join(ctxDir, `${provider}.md`);
|
|
868
|
+
if (!fs.existsSync(providerFile)) {
|
|
869
|
+
const providerContent = `# ${provider.toUpperCase()} Model Configuration
|
|
870
|
+
|
|
871
|
+
## Current Model: ${model || 'Default'}
|
|
872
|
+
|
|
873
|
+
### Model Characteristics
|
|
874
|
+
- **Provider**: ${provider}
|
|
875
|
+
- **Model**: ${model || 'Default model for this provider'}
|
|
876
|
+
- **Context Window**: Varies by model
|
|
877
|
+
- **Strengths**: Add specific strengths of this model
|
|
878
|
+
- **Limitations**: Add specific limitations to be aware of
|
|
879
|
+
|
|
880
|
+
### Best Practices for This Model
|
|
881
|
+
- Write specific coding patterns this model excels at
|
|
882
|
+
- Note any formatting preferences
|
|
883
|
+
- Document prompt engineering tips that work well
|
|
884
|
+
|
|
885
|
+
### Configuration Notes
|
|
886
|
+
- Add any specific configuration notes for this provider
|
|
887
|
+
- Document any rate limits or special considerations
|
|
888
|
+
`;
|
|
889
|
+
fs.writeFileSync(providerFile, providerContent, 'utf-8');
|
|
890
|
+
}
|
|
891
|
+
|
|
827
892
|
const logFile = path.join(ctxDir, 'changes.log.md');
|
|
828
|
-
const logEntry = `## ${new Date().toISOString().slice(0, 10)} — Initial generation\n- Generated ${generatedFiles.length} files\n- Tokens in: ${totalTokensIn} / out: ${totalTokensOut}\n- Description: ${description}\n`;
|
|
893
|
+
const logEntry = `## ${new Date().toISOString().slice(0, 10)} — Initial generation\n- Generated ${generatedFiles.length} files\n- Tokens in: ${totalTokensIn} / out: ${totalTokensOut}\n- Description: ${description}\n- Provider: ${provider} (${model || 'default'})\n`;
|
|
829
894
|
fs.writeFileSync(logFile, (fs.existsSync(logFile) ? fs.readFileSync(logFile, 'utf-8') : '') + logEntry, 'utf-8');
|
|
830
895
|
|
|
831
896
|
emit({ type: 'done', tokIn: totalTokensIn, tokOut: totalTokensOut });
|