neoagent 1.0.0

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.
Files changed (54) hide show
  1. package/.env.example +28 -0
  2. package/LICENSE +21 -0
  3. package/README.md +42 -0
  4. package/bin/neoagent.js +8 -0
  5. package/com.neoagent.plist +45 -0
  6. package/docs/configuration.md +45 -0
  7. package/docs/skills.md +45 -0
  8. package/lib/manager.js +459 -0
  9. package/package.json +61 -0
  10. package/server/db/database.js +239 -0
  11. package/server/index.js +442 -0
  12. package/server/middleware/auth.js +35 -0
  13. package/server/public/app.html +559 -0
  14. package/server/public/css/app.css +608 -0
  15. package/server/public/css/styles.css +472 -0
  16. package/server/public/favicon.svg +17 -0
  17. package/server/public/js/app.js +3283 -0
  18. package/server/public/login.html +313 -0
  19. package/server/routes/agents.js +125 -0
  20. package/server/routes/auth.js +105 -0
  21. package/server/routes/browser.js +116 -0
  22. package/server/routes/mcp.js +164 -0
  23. package/server/routes/memory.js +193 -0
  24. package/server/routes/messaging.js +153 -0
  25. package/server/routes/protocols.js +87 -0
  26. package/server/routes/scheduler.js +63 -0
  27. package/server/routes/settings.js +98 -0
  28. package/server/routes/skills.js +107 -0
  29. package/server/routes/store.js +1192 -0
  30. package/server/services/ai/compaction.js +82 -0
  31. package/server/services/ai/engine.js +1690 -0
  32. package/server/services/ai/models.js +46 -0
  33. package/server/services/ai/multiStep.js +112 -0
  34. package/server/services/ai/providers/anthropic.js +181 -0
  35. package/server/services/ai/providers/base.js +40 -0
  36. package/server/services/ai/providers/google.js +187 -0
  37. package/server/services/ai/providers/grok.js +121 -0
  38. package/server/services/ai/providers/ollama.js +162 -0
  39. package/server/services/ai/providers/openai.js +167 -0
  40. package/server/services/ai/toolRunner.js +218 -0
  41. package/server/services/browser/controller.js +320 -0
  42. package/server/services/cli/executor.js +204 -0
  43. package/server/services/mcp/client.js +260 -0
  44. package/server/services/memory/embeddings.js +126 -0
  45. package/server/services/memory/manager.js +431 -0
  46. package/server/services/messaging/base.js +23 -0
  47. package/server/services/messaging/discord.js +238 -0
  48. package/server/services/messaging/manager.js +328 -0
  49. package/server/services/messaging/telegram.js +243 -0
  50. package/server/services/messaging/telnyx.js +693 -0
  51. package/server/services/messaging/whatsapp.js +304 -0
  52. package/server/services/scheduler/cron.js +312 -0
  53. package/server/services/websocket.js +191 -0
  54. package/server/utils/security.js +71 -0
@@ -0,0 +1,82 @@
1
+ async function compact(messages, provider, model) {
2
+ const systemMsg = messages.find(m => m.role === 'system');
3
+ const nonSystem = messages.filter(m => m.role !== 'system');
4
+
5
+ if (nonSystem.length < 6) return messages;
6
+
7
+ const keepRecent = 6;
8
+ const toCompact = nonSystem.slice(0, -keepRecent);
9
+ const recent = nonSystem.slice(-keepRecent);
10
+
11
+ let compactionText = '';
12
+ for (const msg of toCompact) {
13
+ if (msg.role === 'user') {
14
+ compactionText += `User: ${(msg.content || '').slice(0, 500)}\n`;
15
+ } else if (msg.role === 'assistant') {
16
+ const content = (msg.content || '').slice(0, 500);
17
+ if (msg.tool_calls) {
18
+ const tools = msg.tool_calls.map(tc => tc.function.name).join(', ');
19
+ compactionText += `Assistant: [used tools: ${tools}] ${content}\n`;
20
+ } else {
21
+ compactionText += `Assistant: ${content}\n`;
22
+ }
23
+ } else if (msg.role === 'tool') {
24
+ const result = (msg.content || '').slice(0, 200);
25
+ compactionText += `Tool result: ${result}\n`;
26
+ }
27
+ }
28
+
29
+ const summaryPrompt = [
30
+ { role: 'system', content: 'Summarize this conversation history concisely. Preserve: key decisions, facts learned, user preferences, task outcomes, and any errors or important results. Be thorough but compact.' },
31
+ { role: 'user', content: `Summarize this conversation:\n\n${compactionText}` }
32
+ ];
33
+
34
+ try {
35
+ const response = await provider.chat(summaryPrompt, [], { model, maxTokens: 2000 });
36
+ const summary = response.content || 'Previous conversation context (summary unavailable).';
37
+
38
+ const compactedMessages = [];
39
+ if (systemMsg) compactedMessages.push(systemMsg);
40
+ compactedMessages.push({
41
+ role: 'user',
42
+ content: `[Previous conversation summary]\n${summary}`
43
+ });
44
+ compactedMessages.push({
45
+ role: 'assistant',
46
+ content: 'Understood. I have the context from our previous conversation. Continuing.'
47
+ });
48
+ compactedMessages.push(...recent);
49
+
50
+ return compactedMessages;
51
+ } catch (err) {
52
+ console.error('Compaction failed:', err.message);
53
+ const trimmed = [];
54
+ if (systemMsg) trimmed.push(systemMsg);
55
+ trimmed.push({
56
+ role: 'user',
57
+ content: '[Earlier conversation context was trimmed due to length]'
58
+ });
59
+ trimmed.push({
60
+ role: 'assistant',
61
+ content: 'Understood. Some earlier context was trimmed. Continuing with recent messages.'
62
+ });
63
+ trimmed.push(...recent);
64
+ return trimmed;
65
+ }
66
+ }
67
+
68
+ function estimateTokenCount(messages) {
69
+ let count = 0;
70
+ for (const msg of messages) {
71
+ if (msg.content) count += Math.ceil(msg.content.length / 4);
72
+ if (msg.tool_calls) count += Math.ceil(JSON.stringify(msg.tool_calls).length / 4);
73
+ }
74
+ return count;
75
+ }
76
+
77
+ function shouldCompact(messages, contextWindow) {
78
+ const used = estimateTokenCount(messages);
79
+ return used > contextWindow * 0.85;
80
+ }
81
+
82
+ module.exports = { compact, estimateTokenCount, shouldCompact };