neoagent 2.4.1-beta.19 → 2.4.1-beta.21
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 +4 -1
- package/docs/getting-started.md +9 -3
- package/flutter_app/assets/branding/app_icon_light_1024.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_128.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_192.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_256.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_32.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_512.png +0 -0
- package/flutter_app/assets/branding/app_icon_light_64.png +0 -0
- package/flutter_app/assets/branding/tray_icon_light_template.png +0 -0
- package/flutter_app/lib/features/location/location_service.dart +3 -0
- package/flutter_app/lib/main.dart +1 -0
- package/flutter_app/lib/main_account_settings.dart +9 -33
- package/flutter_app/lib/main_app_shell.dart +237 -197
- package/flutter_app/lib/main_controller.dart +0 -25
- package/flutter_app/lib/main_devices.dart +2 -0
- package/flutter_app/lib/main_models.dart +144 -0
- package/flutter_app/lib/main_operations.dart +150 -19
- package/flutter_app/lib/main_shared.dart +642 -195
- package/flutter_app/lib/main_theme.dart +2 -0
- package/flutter_app/lib/src/android_apk_drop_zone_web.dart +3 -1
- package/flutter_app/lib/src/security/password_strength.dart +84 -0
- package/flutter_app/lib/src/theme/palette.dart +15 -15
- package/flutter_app/pubspec.yaml +3 -0
- package/flutter_app/web/favicon_light.svg +3 -0
- package/flutter_app/web/icons/Icon-192-light.png +0 -0
- package/flutter_app/web/icons/Icon-512-light.png +0 -0
- package/flutter_app/web/icons/Icon-maskable-192-light.png +0 -0
- package/flutter_app/web/icons/Icon-maskable-512-light.png +0 -0
- package/lib/manager.js +282 -81
- package/package.json +17 -3
- package/server/config/origins.js +3 -1
- package/server/db/database.js +73 -0
- package/server/public/.last_build_id +1 -1
- package/server/public/assets/AssetManifest.bin +1 -1
- package/server/public/assets/AssetManifest.bin.json +1 -1
- package/server/public/assets/assets/branding/app_icon_light_256.png +0 -0
- package/server/public/assets/assets/branding/app_icon_light_512.png +0 -0
- package/server/public/assets/assets/branding/tray_icon_light_template.png +0 -0
- package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
- package/server/public/favicon_light.svg +3 -0
- package/server/public/flutter_bootstrap.js +1 -1
- package/server/public/icons/Icon-192-light.png +0 -0
- package/server/public/icons/Icon-512-light.png +0 -0
- package/server/public/icons/Icon-maskable-192-light.png +0 -0
- package/server/public/icons/Icon-maskable-512-light.png +0 -0
- package/server/public/main.dart.js +68769 -68268
- package/server/routes/agent_profiles.js +3 -0
- package/server/routes/memory.js +22 -1
- package/server/services/account/password_policy.js +6 -1
- package/server/services/memory/intelligence.js +181 -0
- package/server/services/memory/manager.js +475 -25
- package/server/utils/security.js +3 -0
- package/server/services/memory/openhuman_uplift.test.js +0 -98
- package/server/utils/version.test.js +0 -39
package/server/utils/security.js
CHANGED
|
@@ -15,6 +15,9 @@ function sanitizeError(err) {
|
|
|
15
15
|
const raw = typeof err === 'string' ? err : err.message || String(err);
|
|
16
16
|
|
|
17
17
|
let msg = raw;
|
|
18
|
+
if (!msg || msg === '[object Object]') {
|
|
19
|
+
msg = 'An unexpected error occurred';
|
|
20
|
+
}
|
|
18
21
|
|
|
19
22
|
// Replace home directory path with ~
|
|
20
23
|
if (HOME) {
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const assert = require('node:assert/strict');
|
|
4
|
-
const test = require('node:test');
|
|
5
|
-
const { randomUUID } = require('node:crypto');
|
|
6
|
-
|
|
7
|
-
process.env.OPENAI_API_KEY = '';
|
|
8
|
-
process.env.GOOGLE_AI_KEY = '';
|
|
9
|
-
|
|
10
|
-
const db = require('../../db/database');
|
|
11
|
-
const { resolveAgentId } = require('../agents/manager');
|
|
12
|
-
const { compactTextPayload } = require('../ai/preModelCompaction');
|
|
13
|
-
const { MemoryManager } = require('./manager');
|
|
14
|
-
const { MemoryIngestionService, sourceTypesForConnection } = require('./ingestion');
|
|
15
|
-
const { buildAssistantFocusSnapshot } = require('../widgets/focus_widget');
|
|
16
|
-
|
|
17
|
-
function createTestUser() {
|
|
18
|
-
const username = `openhuman-${randomUUID()}`;
|
|
19
|
-
const result = db.prepare(
|
|
20
|
-
'INSERT INTO users (username, password) VALUES (?, ?)',
|
|
21
|
-
).run(username, 'test');
|
|
22
|
-
const userId = Number(result.lastInsertRowid);
|
|
23
|
-
return {
|
|
24
|
-
userId,
|
|
25
|
-
agentId: resolveAgentId(userId, null),
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function cleanupUser(userId) {
|
|
30
|
-
db.prepare('DELETE FROM users WHERE id = ?').run(userId);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
test('pre-model compaction strips noisy HTML and records metrics', () => {
|
|
34
|
-
const input = '<html><style>.x{}</style><body>Read https://example.com/a/really/long/path today.<br>Read https://example.com/a/really/long/path today.</body></html>';
|
|
35
|
-
const result = compactTextPayload(input, { maxChars: 120, maxLines: 5 });
|
|
36
|
-
|
|
37
|
-
assert.equal(result.metrics.applied, true);
|
|
38
|
-
assert.ok(result.metrics.strategies.includes('html_to_text'));
|
|
39
|
-
assert.ok(result.metrics.strategies.includes('url_shortening'));
|
|
40
|
-
assert.match(result.text, /example\.com/);
|
|
41
|
-
assert.doesNotMatch(result.text, /<body>/);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
test('memory ingestion writes typed documents, memory, and materialized views', async () => {
|
|
45
|
-
const { userId, agentId } = createTestUser();
|
|
46
|
-
const memoryManager = new MemoryManager();
|
|
47
|
-
const service = new MemoryIngestionService({ memoryManager, intervalMs: 60_000 });
|
|
48
|
-
|
|
49
|
-
try {
|
|
50
|
-
const result = await service.ingestDocuments(userId, [
|
|
51
|
-
{
|
|
52
|
-
externalObjectId: 'thread-123',
|
|
53
|
-
sourceType: 'email',
|
|
54
|
-
normalizedType: 'email',
|
|
55
|
-
title: 'Launch review',
|
|
56
|
-
content: 'The launch review moved to Friday. Alice owns the deck and Bob owns QA.',
|
|
57
|
-
sourceAccount: 'team@example.com',
|
|
58
|
-
salience: 8,
|
|
59
|
-
},
|
|
60
|
-
], {
|
|
61
|
-
agentId,
|
|
62
|
-
sourceType: 'email',
|
|
63
|
-
providerKey: 'google_workspace',
|
|
64
|
-
sourceAccount: 'team@example.com',
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
assert.equal(result.status, 'completed');
|
|
68
|
-
assert.equal(result.documentIds.length, 1);
|
|
69
|
-
assert.equal(result.memoryIds.length, 1);
|
|
70
|
-
|
|
71
|
-
const docs = memoryManager.listIngestionDocuments(userId, {
|
|
72
|
-
agentId,
|
|
73
|
-
providerKey: 'google_workspace',
|
|
74
|
-
});
|
|
75
|
-
assert.equal(docs.length, 1);
|
|
76
|
-
assert.equal(docs[0].sourceType, 'email');
|
|
77
|
-
assert.equal(docs[0].sourceAccount, 'team@example.com');
|
|
78
|
-
|
|
79
|
-
const changes = memoryManager.listRecentKnowledgeChanges(userId, { agentId });
|
|
80
|
-
assert.ok(changes.some((change) => change.kind === 'document'));
|
|
81
|
-
|
|
82
|
-
const views = memoryManager.listKnowledgeViews(userId, { agentId });
|
|
83
|
-
assert.ok(views.some((view) => view.viewType === 'timeline'));
|
|
84
|
-
assert.ok(views.some((view) => view.viewType === 'account'));
|
|
85
|
-
|
|
86
|
-
const focus = buildAssistantFocusSnapshot(memoryManager, userId, agentId);
|
|
87
|
-
assert.equal(focus.backgroundAwareness.changedCount > 0, true);
|
|
88
|
-
assert.ok(focus.recentKnowledgeChanges.some((change) => change.title === 'Launch review'));
|
|
89
|
-
} finally {
|
|
90
|
-
cleanupUser(userId);
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
test('integration coverage maps connected apps to durable memory domains', () => {
|
|
95
|
-
assert.deepEqual(sourceTypesForConnection('google_workspace', 'gmail'), ['email']);
|
|
96
|
-
assert.deepEqual(sourceTypesForConnection('github', 'repos'), ['repos', 'tickets']);
|
|
97
|
-
assert.deepEqual(sourceTypesForConnection('spotify', 'spotify'), []);
|
|
98
|
-
});
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const assert = require('assert');
|
|
4
|
-
const { test } = require('node:test');
|
|
5
|
-
const childProcess = require('child_process');
|
|
6
|
-
|
|
7
|
-
const VERSION_MODULE_PATH = require.resolve('./version');
|
|
8
|
-
|
|
9
|
-
function loadVersionModuleWithExecSync(execSync) {
|
|
10
|
-
const originalExecSync = childProcess.execSync;
|
|
11
|
-
delete require.cache[VERSION_MODULE_PATH];
|
|
12
|
-
childProcess.execSync = execSync;
|
|
13
|
-
try {
|
|
14
|
-
return require('./version');
|
|
15
|
-
} finally {
|
|
16
|
-
childProcess.execSync = originalExecSync;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
test('getVersionInfo caches git metadata reads', () => {
|
|
21
|
-
let callCount = 0;
|
|
22
|
-
const { getVersionInfo } = loadVersionModuleWithExecSync((command) => {
|
|
23
|
-
callCount += 1;
|
|
24
|
-
if (command.includes('describe')) return 'v1.2.3\n';
|
|
25
|
-
if (command.includes('rev-parse --short')) return 'abc123\n';
|
|
26
|
-
if (command.includes('abbrev-ref')) return 'main\n';
|
|
27
|
-
throw new Error(`unexpected command: ${command}`);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
const first = getVersionInfo();
|
|
31
|
-
const second = getVersionInfo();
|
|
32
|
-
|
|
33
|
-
assert.equal(first.gitVersion, '1.2.3');
|
|
34
|
-
assert.equal(first.gitSha, 'abc123');
|
|
35
|
-
assert.equal(first.gitBranch, 'main');
|
|
36
|
-
assert.equal(second.gitVersion, '1.2.3');
|
|
37
|
-
assert.equal(callCount, 3);
|
|
38
|
-
});
|
|
39
|
-
|