neoagent 2.1.18-beta.2 → 2.1.18-beta.4
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/.env.example +17 -0
- package/docs/configuration.md +9 -2
- package/lib/manager.js +87 -19
- package/package.json +1 -1
- package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
- package/server/public/flutter_bootstrap.js +1 -1
- package/server/public/main.dart.js +30566 -30588
- package/server/routes/settings.js +16 -0
- package/server/services/ai/capabilityHealth.js +16 -3
- package/server/services/ai/engine.js +4 -0
- package/server/services/ai/models.js +14 -24
- package/server/services/ai/settings.js +0 -4
- package/server/services/ai/systemPrompt.js +2 -0
- package/server/services/ai/tools.js +8 -1
- package/server/services/integrations/env.js +4 -3
- package/server/services/integrations/google/provider.js +49 -6
- package/server/services/memory/manager.js +4 -1
- package/server/services/memory/policy.js +67 -0
- package/server/utils/deployment.js +49 -0
- package/server/utils/version.js +5 -0
package/.env.example
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
PORT=3333
|
|
2
2
|
NODE_ENV=development
|
|
3
3
|
SESSION_SECRET=change-this-to-a-random-secret-in-production
|
|
4
|
+
PUBLIC_URL=
|
|
5
|
+
SECURE_COOKIES=false
|
|
6
|
+
NEOAGENT_DEPLOYMENT_MODE=self_hosted
|
|
7
|
+
NEOAGENT_RELEASE_CHANNEL=stable
|
|
4
8
|
|
|
5
9
|
# Comma-separated list of allowed CORS origins (leave empty to block all cross-origin requests)
|
|
6
10
|
# Example: ALLOWED_ORIGINS=http://localhost:3333,https://yourdomain.com
|
|
@@ -12,6 +16,7 @@ ALLOWED_ORIGINS=
|
|
|
12
16
|
# • Image vision / analysis (grok-4-1-fast-reasoning has native image input — analyze_image tool, incoming WhatsApp photos)
|
|
13
17
|
# Get your key at: https://console.x.ai
|
|
14
18
|
XAI_API_KEY=your-xai-api-key-here
|
|
19
|
+
# XAI_BASE_URL=https://api.x.ai/v1
|
|
15
20
|
|
|
16
21
|
# OpenAI API key — used for:
|
|
17
22
|
# • Semantic memory embeddings (text-embedding-3-small, 1536 dims)
|
|
@@ -21,6 +26,12 @@ XAI_API_KEY=your-xai-api-key-here
|
|
|
21
26
|
# Without this key: memory falls back to keyword search, voice calls and WhatsApp audio transcription are unavailable.
|
|
22
27
|
# Get your key at: https://platform.openai.com/api-keys
|
|
23
28
|
OPENAI_API_KEY=your-openai-api-key-here
|
|
29
|
+
# OPENAI_BASE_URL=https://your-openai-compatible-endpoint/v1
|
|
30
|
+
|
|
31
|
+
# Anthropic API key — used for:
|
|
32
|
+
# • Claude models for long-context drafting and analysis
|
|
33
|
+
ANTHROPIC_API_KEY=your-anthropic-api-key-here
|
|
34
|
+
# ANTHROPIC_BASE_URL=https://your-anthropic-compatible-endpoint
|
|
24
35
|
|
|
25
36
|
# Google AI Studio API key — used for:
|
|
26
37
|
# • Gemini models (e.g. gemini-3.1-flash-lite-preview)
|
|
@@ -43,5 +54,11 @@ BRAVE_SEARCH_API_KEY=your-brave-search-api-key-here
|
|
|
43
54
|
# Without this key: recordings can still be captured and stored, but transcription will fail until retried with a valid key.
|
|
44
55
|
# Get your key at: https://console.deepgram.com/
|
|
45
56
|
DEEPGRAM_API_KEY=your-deepgram-api-key-here
|
|
57
|
+
DEEPGRAM_BASE_URL=https://api.deepgram.com
|
|
46
58
|
DEEPGRAM_MODEL=nova-3
|
|
47
59
|
DEEPGRAM_LANGUAGE=multi
|
|
60
|
+
|
|
61
|
+
# Optional additional providers and services
|
|
62
|
+
# MINIMAX_API_KEY=your-minimax-api-key-here
|
|
63
|
+
# OLLAMA_URL=http://localhost:11434
|
|
64
|
+
# TELNYX_WEBHOOK_TOKEN=replace-me
|
package/docs/configuration.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Configuration
|
|
2
2
|
|
|
3
|
-
All settings live in `~/.neoagent/.env` by default. Run `neoagent setup` to regenerate interactively. If a self-edit or local install issue leaves NeoAgent broken,
|
|
3
|
+
All settings live in `~/.neoagent/.env` by default. Run `neoagent setup` to regenerate interactively. AI provider credentials are configured through the server environment or `neoagent setup`, not through the web UI. If a self-edit or local install issue leaves NeoAgent broken, rerun setup or restore the env file and restart the service.
|
|
4
4
|
You can override the runtime root with `NEOAGENT_HOME`.
|
|
5
5
|
|
|
6
6
|
## Variables
|
|
@@ -10,27 +10,34 @@ You can override the runtime root with `NEOAGENT_HOME`.
|
|
|
10
10
|
| Variable | Default | Description |
|
|
11
11
|
|---|---|---|
|
|
12
12
|
| `PORT` | `3333` | HTTP port |
|
|
13
|
+
| `PUBLIC_URL` | *(optional)* | Public base URL used for callbacks and external links |
|
|
13
14
|
| `SESSION_SECRET` | *(required)* | Random string for session signing — generate with `openssl rand -hex 32` |
|
|
14
15
|
| `NODE_ENV` | `production` | Set to `development` to enable verbose logs |
|
|
15
16
|
| `SECURE_COOKIES` | `false` | Set `true` when behind a TLS-terminating proxy |
|
|
16
17
|
| `ALLOWED_ORIGINS` | *(none)* | Comma-separated CORS origins, e.g. `https://example.com` |
|
|
18
|
+
| `NEOAGENT_DEPLOYMENT_MODE` | `self_hosted` | `self_hosted` enables in-app update controls; `managed` hides operator-only controls for SaaS deployments |
|
|
19
|
+
| `NEOAGENT_RELEASE_CHANNEL` | `stable` | Release track used by the self-hosted updater |
|
|
17
20
|
|
|
18
21
|
### AI Providers
|
|
19
22
|
|
|
20
|
-
At least one API key is required. The active provider and model are configured in the Flutter app.
|
|
23
|
+
At least one hosted-provider API key is required unless you only use local Ollama. The active provider and model routing are configured in the Flutter app; credentials stay in server-side config.
|
|
21
24
|
|
|
22
25
|
| Variable | Provider |
|
|
23
26
|
|---|---|
|
|
24
27
|
| `ANTHROPIC_API_KEY` | Claude (Anthropic) |
|
|
25
28
|
| `OPENAI_API_KEY` | GPT-4o / Whisper (OpenAI) |
|
|
26
29
|
| `XAI_API_KEY` | Grok (xAI) |
|
|
30
|
+
| `XAI_BASE_URL` | Optional xAI-compatible base URL override |
|
|
27
31
|
| `GOOGLE_AI_KEY` | Gemini (Google) |
|
|
28
32
|
| `GOOGLE_OAUTH_CLIENT_ID` | Google Workspace official integrations OAuth client ID |
|
|
29
33
|
| `GOOGLE_OAUTH_CLIENT_SECRET` | Google Workspace official integrations OAuth client secret |
|
|
30
34
|
| `GOOGLE_OAUTH_REDIRECT_URI` | Optional override for the Google Workspace OAuth callback URL |
|
|
31
35
|
| `MINIMAX_API_KEY` | MiniMax Code (Coding Plan / Token Plan for `MiniMax-M2.7`) |
|
|
32
36
|
| `BRAVE_SEARCH_API_KEY` | Brave Search API for the native `web_search` tool |
|
|
37
|
+
| `OPENAI_BASE_URL` | Optional OpenAI-compatible base URL override |
|
|
38
|
+
| `ANTHROPIC_BASE_URL` | Optional Anthropic-compatible base URL override |
|
|
33
39
|
| `DEEPGRAM_API_KEY` | Recordings transcription with Deepgram Nova-3 multilingual |
|
|
40
|
+
| `DEEPGRAM_BASE_URL` | Optional Deepgram API base URL override |
|
|
34
41
|
| `DEEPGRAM_MODEL` | Deepgram speech model override (defaults to `nova-3`) |
|
|
35
42
|
| `DEEPGRAM_LANGUAGE` | Deepgram language override (defaults to `multi`) |
|
|
36
43
|
| `OLLAMA_URL` | Local Ollama (`http://localhost:11434`) |
|
package/lib/manager.js
CHANGED
|
@@ -31,6 +31,7 @@ const {
|
|
|
31
31
|
choosePreferredBranchForChannel,
|
|
32
32
|
choosePreferredNpmTagForChannel,
|
|
33
33
|
} = require('../runtime/release_channel');
|
|
34
|
+
const { parseDeploymentMode } = require('../server/utils/deployment');
|
|
34
35
|
|
|
35
36
|
const APP_NAME = 'NeoAgent';
|
|
36
37
|
const SERVICE_LABEL = 'com.neoagent';
|
|
@@ -417,43 +418,110 @@ async function ask(question, fallback = '') {
|
|
|
417
418
|
});
|
|
418
419
|
}
|
|
419
420
|
|
|
421
|
+
async function askSecret(question, currentValue = '') {
|
|
422
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
423
|
+
return new Promise((resolve) => {
|
|
424
|
+
const suffix = currentValue ? ' [configured]' : '';
|
|
425
|
+
rl.question(` ? ${question}${suffix}: `, (answer) => {
|
|
426
|
+
rl.close();
|
|
427
|
+
const trimmed = answer.trim();
|
|
428
|
+
resolve(trimmed || currentValue);
|
|
429
|
+
});
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
|
|
420
433
|
async function cmdSetup() {
|
|
421
434
|
heading('Environment Setup');
|
|
422
435
|
ensureRuntimeDirs();
|
|
423
436
|
|
|
424
|
-
const current =
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
for (const line of lines) {
|
|
428
|
-
if (!line || line.startsWith('#') || !line.includes('=')) continue;
|
|
429
|
-
const idx = line.indexOf('=');
|
|
430
|
-
const key = line.slice(0, idx).trim();
|
|
431
|
-
const value = line.slice(idx + 1).trim();
|
|
432
|
-
current[key] = value;
|
|
433
|
-
}
|
|
434
|
-
}
|
|
437
|
+
const current = Object.fromEntries(parseEnv(readEnvFileRaw()).entries());
|
|
438
|
+
|
|
439
|
+
logInfo('Press Enter to keep the current value shown in brackets.');
|
|
435
440
|
|
|
441
|
+
heading('Core');
|
|
436
442
|
const port = await ask('Server port', current.PORT || '3333');
|
|
437
|
-
const
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
const
|
|
441
|
-
const
|
|
442
|
-
const
|
|
443
|
-
|
|
444
|
-
|
|
443
|
+
const publicUrl = await ask('Public base URL', current.PUBLIC_URL || '');
|
|
444
|
+
const secureCookiesDefault = current.SECURE_COOKIES ||
|
|
445
|
+
(String(publicUrl || '').trim().startsWith('https://') ? 'true' : 'false');
|
|
446
|
+
const secureCookies = await ask('Secure cookies (true/false)', secureCookiesDefault);
|
|
447
|
+
const sessionSecret = await askSecret('Session secret', current.SESSION_SECRET || randomSecret());
|
|
448
|
+
const deploymentMode = await ask(
|
|
449
|
+
'Deployment mode (self_hosted/managed)',
|
|
450
|
+
current.NEOAGENT_DEPLOYMENT_MODE || 'self_hosted'
|
|
451
|
+
);
|
|
452
|
+
const releaseChannel = await ask(
|
|
453
|
+
'Release channel (stable/beta)',
|
|
454
|
+
current.NEOAGENT_RELEASE_CHANNEL || 'stable'
|
|
455
|
+
);
|
|
445
456
|
const origins = await ask('Allowed CORS origins', current.ALLOWED_ORIGINS || '');
|
|
446
457
|
|
|
458
|
+
heading('AI Providers');
|
|
459
|
+
const anthropic = await askSecret('Anthropic API key', current.ANTHROPIC_API_KEY || '');
|
|
460
|
+
const anthropicBaseUrl = await ask('Anthropic base URL', current.ANTHROPIC_BASE_URL || '');
|
|
461
|
+
const openai = await askSecret('OpenAI API key', current.OPENAI_API_KEY || '');
|
|
462
|
+
const openaiBaseUrl = await ask('OpenAI base URL', current.OPENAI_BASE_URL || '');
|
|
463
|
+
const xai = await askSecret('xAI API key', current.XAI_API_KEY || '');
|
|
464
|
+
const xaiBaseUrl = await ask('xAI base URL', current.XAI_BASE_URL || 'https://api.x.ai/v1');
|
|
465
|
+
const google = await askSecret('Google API key', current.GOOGLE_AI_KEY || '');
|
|
466
|
+
const minimax = await askSecret('MiniMax Code key', current.MINIMAX_API_KEY || '');
|
|
467
|
+
const brave = await askSecret('Brave Search API key', current.BRAVE_SEARCH_API_KEY || '');
|
|
468
|
+
const ollama = await ask('Ollama URL', current.OLLAMA_URL || 'http://localhost:11434');
|
|
469
|
+
|
|
470
|
+
heading('Official Integrations');
|
|
471
|
+
const googleOauthClientId = await askSecret(
|
|
472
|
+
'Google OAuth client ID',
|
|
473
|
+
current.GOOGLE_OAUTH_CLIENT_ID || ''
|
|
474
|
+
);
|
|
475
|
+
const googleOauthClientSecret = await askSecret(
|
|
476
|
+
'Google OAuth client secret',
|
|
477
|
+
current.GOOGLE_OAUTH_CLIENT_SECRET || ''
|
|
478
|
+
);
|
|
479
|
+
const googleOauthRedirectUri = await ask(
|
|
480
|
+
'Google OAuth redirect URI',
|
|
481
|
+
current.GOOGLE_OAUTH_REDIRECT_URI || ''
|
|
482
|
+
);
|
|
483
|
+
|
|
484
|
+
heading('Voice And Recording');
|
|
485
|
+
const deepgramApiKey = await askSecret('Deepgram API key', current.DEEPGRAM_API_KEY || '');
|
|
486
|
+
const deepgramBaseUrl = await ask(
|
|
487
|
+
'Deepgram base URL',
|
|
488
|
+
current.DEEPGRAM_BASE_URL || 'https://api.deepgram.com'
|
|
489
|
+
);
|
|
490
|
+
const deepgramModel = await ask('Deepgram model', current.DEEPGRAM_MODEL || 'nova-3');
|
|
491
|
+
const deepgramLanguage = await ask('Deepgram language', current.DEEPGRAM_LANGUAGE || 'multi');
|
|
492
|
+
const telnyxWebhookToken = await askSecret(
|
|
493
|
+
'Telnyx webhook token',
|
|
494
|
+
current.TELNYX_WEBHOOK_TOKEN || ''
|
|
495
|
+
);
|
|
496
|
+
const normalizedSecureCookies = String(secureCookies || '').trim().toLowerCase() === 'true' ? 'true' : 'false';
|
|
497
|
+
const normalizedDeploymentMode = parseDeploymentMode(deploymentMode);
|
|
498
|
+
const normalizedReleaseChannel = parseReleaseChannel(releaseChannel) || 'stable';
|
|
499
|
+
|
|
447
500
|
const lines = [
|
|
448
501
|
`NODE_ENV=production`,
|
|
449
502
|
`PORT=${port}`,
|
|
503
|
+
publicUrl ? `PUBLIC_URL=${publicUrl}` : '',
|
|
504
|
+
`SECURE_COOKIES=${normalizedSecureCookies}`,
|
|
450
505
|
`SESSION_SECRET=${sessionSecret}`,
|
|
506
|
+
`NEOAGENT_DEPLOYMENT_MODE=${normalizedDeploymentMode}`,
|
|
507
|
+
`NEOAGENT_RELEASE_CHANNEL=${normalizedReleaseChannel}`,
|
|
451
508
|
anthropic ? `ANTHROPIC_API_KEY=${anthropic}` : '',
|
|
509
|
+
anthropicBaseUrl ? `ANTHROPIC_BASE_URL=${anthropicBaseUrl}` : '',
|
|
452
510
|
openai ? `OPENAI_API_KEY=${openai}` : '',
|
|
511
|
+
openaiBaseUrl ? `OPENAI_BASE_URL=${openaiBaseUrl}` : '',
|
|
453
512
|
xai ? `XAI_API_KEY=${xai}` : '',
|
|
513
|
+
xaiBaseUrl ? `XAI_BASE_URL=${xaiBaseUrl}` : '',
|
|
454
514
|
google ? `GOOGLE_AI_KEY=${google}` : '',
|
|
455
515
|
minimax ? `MINIMAX_API_KEY=${minimax}` : '',
|
|
456
516
|
brave ? `BRAVE_SEARCH_API_KEY=${brave}` : '',
|
|
517
|
+
googleOauthClientId ? `GOOGLE_OAUTH_CLIENT_ID=${googleOauthClientId}` : '',
|
|
518
|
+
googleOauthClientSecret ? `GOOGLE_OAUTH_CLIENT_SECRET=${googleOauthClientSecret}` : '',
|
|
519
|
+
googleOauthRedirectUri ? `GOOGLE_OAUTH_REDIRECT_URI=${googleOauthRedirectUri}` : '',
|
|
520
|
+
deepgramApiKey ? `DEEPGRAM_API_KEY=${deepgramApiKey}` : '',
|
|
521
|
+
deepgramBaseUrl ? `DEEPGRAM_BASE_URL=${deepgramBaseUrl}` : '',
|
|
522
|
+
deepgramModel ? `DEEPGRAM_MODEL=${deepgramModel}` : '',
|
|
523
|
+
deepgramLanguage ? `DEEPGRAM_LANGUAGE=${deepgramLanguage}` : '',
|
|
524
|
+
telnyxWebhookToken ? `TELNYX_WEBHOOK_TOKEN=${telnyxWebhookToken}` : '',
|
|
457
525
|
ollama ? `OLLAMA_URL=${ollama}` : '',
|
|
458
526
|
origins ? `ALLOWED_ORIGINS=${origins}` : ''
|
|
459
527
|
].filter(Boolean);
|
package/package.json
CHANGED
|
Binary file
|
|
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"425cfb54d01a9472b3e81d9e76fd63a4a44cfb
|
|
|
37
37
|
|
|
38
38
|
_flutter.loader.load({
|
|
39
39
|
serviceWorkerSettings: {
|
|
40
|
-
serviceWorkerVersion: "
|
|
40
|
+
serviceWorkerVersion: "474089705" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
|
|
41
41
|
}
|
|
42
42
|
});
|