neoagent 2.4.1-beta.11 → 2.4.1-beta.13
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/flutter_app/lib/main.dart +1 -0
- package/flutter_app/lib/main_devices.dart +89 -2
- package/flutter_app/lib/main_model_picker.dart +631 -0
- package/flutter_app/lib/main_settings.dart +30 -86
- package/flutter_app/lib/src/android_apk_drop_zone.dart +24 -0
- package/flutter_app/lib/src/android_apk_drop_zone_stub.dart +13 -0
- package/flutter_app/lib/src/android_apk_drop_zone_web.dart +217 -0
- package/lib/manager.js +131 -2
- package/package.json +1 -1
- package/server/public/.last_build_id +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 +58341 -58041
- package/server/services/ai/engine.js +148 -19
- package/server/services/ai/loopPolicy.js +11 -0
- package/server/services/ai/models.js +68 -0
- package/server/services/ai/providers/grokOauth.js +141 -0
- package/server/services/ai/providers/nvidia.js +165 -0
- package/server/services/ai/settings.js +20 -0
- package/server/services/ai/taskAnalysis.js +56 -0
- package/server/services/ai/tools.js +3 -3
- package/server/services/integrations/google/provider.js +13 -0
- package/server/services/integrations/manager.js +5 -0
- package/server/services/integrations/trello/provider.js +8 -2
|
@@ -49,6 +49,26 @@ const AI_PROVIDER_DEFINITIONS = Object.freeze({
|
|
|
49
49
|
defaultEnabled: true,
|
|
50
50
|
defaultBaseUrl: 'https://api.x.ai/v1'
|
|
51
51
|
},
|
|
52
|
+
'grok-oauth': {
|
|
53
|
+
id: 'grok-oauth',
|
|
54
|
+
label: 'Grok (xAI OAuth)',
|
|
55
|
+
description: 'Grok models via xAI account. Login with `neoagent login grok-oauth`.',
|
|
56
|
+
envKey: 'GROK_OAUTH_ACCESS_TOKEN',
|
|
57
|
+
supportsApiKey: true,
|
|
58
|
+
supportsBaseUrl: false,
|
|
59
|
+
defaultEnabled: false,
|
|
60
|
+
defaultBaseUrl: ''
|
|
61
|
+
},
|
|
62
|
+
nvidia: {
|
|
63
|
+
id: 'nvidia',
|
|
64
|
+
label: 'NVIDIA NIM',
|
|
65
|
+
description: 'NVIDIA-hosted models including free-tier Nemotron, Kimi, Llama 4, and DeepSeek. Get a key at build.nvidia.com.',
|
|
66
|
+
envKey: 'NVIDIA_API_KEY',
|
|
67
|
+
supportsApiKey: true,
|
|
68
|
+
supportsBaseUrl: true,
|
|
69
|
+
defaultEnabled: false,
|
|
70
|
+
defaultBaseUrl: 'https://integrate.api.nvidia.com/v1'
|
|
71
|
+
},
|
|
52
72
|
minimax: {
|
|
53
73
|
id: 'minimax',
|
|
54
74
|
label: 'MiniMax Code',
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
const ANALYSIS_MODES = ['direct_answer', 'execute', 'plan_execute'];
|
|
2
2
|
const VERIFICATION_STATUSES = ['verified', 'needs_revision', 'insufficient_evidence'];
|
|
3
|
+
const COMPLEXITY_LEVELS = ['simple', 'standard', 'complex'];
|
|
4
|
+
const AUTONOMY_LEVELS = ['minimal', 'normal', 'high'];
|
|
5
|
+
const PROGRESS_UPDATE_POLICIES = ['none', 'optional', 'required'];
|
|
6
|
+
const COMPLETION_CONFIDENCE_LEVELS = ['medium', 'high'];
|
|
3
7
|
const TASK_ANALYSIS_SUGGESTED_TOOLS_LIMIT = 12;
|
|
4
8
|
const TASK_ANALYSIS_SUCCESS_CRITERIA_LIMIT = 8;
|
|
5
9
|
const PLAN_STEP_SUGGESTED_TOOLS_LIMIT = 8;
|
|
@@ -20,6 +24,11 @@ const ANALYSIS_SCHEMA_EXAMPLE = {
|
|
|
20
24
|
goal: 'Answer the user accurately.',
|
|
21
25
|
success_criteria: ['Final reply is correct and specific.'],
|
|
22
26
|
suggested_tools: ['web_search', 'browser_navigate'],
|
|
27
|
+
complexity: 'standard',
|
|
28
|
+
autonomy_level: 'normal',
|
|
29
|
+
progress_update_policy: 'optional',
|
|
30
|
+
parallel_work: false,
|
|
31
|
+
completion_confidence_required: 'medium',
|
|
23
32
|
};
|
|
24
33
|
const PLAN_SCHEMA_EXAMPLE = {
|
|
25
34
|
steps: [
|
|
@@ -42,6 +51,11 @@ const ANALYSIS_PROMPT_INSTRUCTIONS = [
|
|
|
42
51
|
'Set goal to a concise restatement of what the user is asking for in this message. Never leave goal empty.',
|
|
43
52
|
'Keep goal and success_criteria short and practical.',
|
|
44
53
|
'suggested_tools are optional hints, not a required plan.',
|
|
54
|
+
'Set complexity from the actual work shape, not from keywords: simple, standard, or complex.',
|
|
55
|
+
'Set autonomy_level="high" when the agent should decide sequencing, retries, evidence gathering, and verification without asking the user unless blocked.',
|
|
56
|
+
'Set progress_update_policy="required" for long, slow, voice, messaging, or externally visible work where silence would be confusing.',
|
|
57
|
+
'Set parallel_work=true when independent tool calls or subagents can materially reduce latency.',
|
|
58
|
+
'Set completion_confidence_required="high" when wrong completion would be costly, state-changing, user-visible, or hard to recover.',
|
|
45
59
|
];
|
|
46
60
|
const PLAN_PROMPT_INSTRUCTIONS = [
|
|
47
61
|
'Create a concise execution plan for the current task.',
|
|
@@ -51,6 +65,8 @@ const PLAN_PROMPT_INSTRUCTIONS = [
|
|
|
51
65
|
'For external actions, include a step to draft or confirm before sending unless the user already gave explicit current-session approval.',
|
|
52
66
|
'For code or config changes, include inspection, scoped edit, and verification steps.',
|
|
53
67
|
'For tasks that run later, make the future prompt self-contained and include notification conditions.',
|
|
68
|
+
'Call out independent work that can start before slower blocking work finishes.',
|
|
69
|
+
'Make the final step prove completion against the success criteria, not just produce a plausible answer.',
|
|
54
70
|
];
|
|
55
71
|
const VERIFIER_PROMPT_INSTRUCTIONS = [
|
|
56
72
|
'Verify whether the draft final reply is adequately supported by the gathered evidence.',
|
|
@@ -69,6 +85,7 @@ const EXECUTION_GUIDANCE_ACTION_LINES = [
|
|
|
69
85
|
'When you must ask for missing required user input, ask once, then wait for the reply instead of re-asking in the same run.',
|
|
70
86
|
'For outbound messages, calls, emails, shared edits, installs, restarts, or task mutations, verify the action result before claiming it happened. If user confirmation is required and missing, draft or ask instead of sending.',
|
|
71
87
|
'Retry with alternative tools or approaches when one path fails. If evidence is still insufficient, say so explicitly instead of guessing.',
|
|
88
|
+
'When completion_confidence_required is high, do not call task_complete with low confidence. Verify, inspect, or revise until confidence is at least medium and preferably high.',
|
|
72
89
|
];
|
|
73
90
|
|
|
74
91
|
function buildVerifierSchemaExample(finalReply) {
|
|
@@ -185,6 +202,18 @@ function planningDepthForMode(mode) {
|
|
|
185
202
|
return mode === 'plan_execute' ? 'deep' : mode === 'direct_answer' ? 'none' : 'light';
|
|
186
203
|
}
|
|
187
204
|
|
|
205
|
+
function defaultAutonomyForMode(mode) {
|
|
206
|
+
if (mode === 'direct_answer') return 'minimal';
|
|
207
|
+
if (mode === 'plan_execute') return 'high';
|
|
208
|
+
return 'normal';
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function defaultComplexityForMode(mode) {
|
|
212
|
+
if (mode === 'direct_answer') return 'simple';
|
|
213
|
+
if (mode === 'plan_execute') return 'complex';
|
|
214
|
+
return 'standard';
|
|
215
|
+
}
|
|
216
|
+
|
|
188
217
|
function verificationNeedFor({ mode, needsVerification, hasDraftReply }) {
|
|
189
218
|
if (needsVerification === true) return 'light';
|
|
190
219
|
if (needsVerification === false) {
|
|
@@ -321,6 +350,17 @@ function normalizeTaskAnalysis(raw = {}, fallback = {}) {
|
|
|
321
350
|
planningDepth,
|
|
322
351
|
});
|
|
323
352
|
|
|
353
|
+
const normalizedComplexity = pickEnum(
|
|
354
|
+
resolveAliasedValue(raw, fallback, 'complexity', 'complexity', ''),
|
|
355
|
+
COMPLEXITY_LEVELS,
|
|
356
|
+
defaultComplexityForMode(mode),
|
|
357
|
+
);
|
|
358
|
+
const normalizedAutonomyLevel = pickEnum(
|
|
359
|
+
resolveAliasedValue(raw, fallback, 'autonomy_level', 'autonomyLevel', ''),
|
|
360
|
+
AUTONOMY_LEVELS,
|
|
361
|
+
defaultAutonomyForMode(mode),
|
|
362
|
+
);
|
|
363
|
+
|
|
324
364
|
return {
|
|
325
365
|
mode,
|
|
326
366
|
freshness_risk: freshnessRisk,
|
|
@@ -336,6 +376,19 @@ function normalizeTaskAnalysis(raw = {}, fallback = {}) {
|
|
|
336
376
|
draft_reply: draftReply,
|
|
337
377
|
goal: resolveAliasedText(raw, fallback, 'goal', 'goal', ''),
|
|
338
378
|
success_criteria: successCriteria,
|
|
379
|
+
complexity: mode === 'plan_execute' ? 'complex' : normalizedComplexity,
|
|
380
|
+
autonomy_level: mode === 'plan_execute' ? 'high' : normalizedAutonomyLevel,
|
|
381
|
+
progress_update_policy: pickEnum(
|
|
382
|
+
resolveAliasedValue(raw, fallback, 'progress_update_policy', 'progressUpdatePolicy', ''),
|
|
383
|
+
PROGRESS_UPDATE_POLICIES,
|
|
384
|
+
mode === 'direct_answer' ? 'none' : 'optional',
|
|
385
|
+
),
|
|
386
|
+
parallel_work: resolveAliasedBoolean(raw, fallback, 'parallel_work', 'parallelWork'),
|
|
387
|
+
completion_confidence_required: pickEnum(
|
|
388
|
+
resolveAliasedValue(raw, fallback, 'completion_confidence_required', 'completionConfidenceRequired', ''),
|
|
389
|
+
COMPLETION_CONFIDENCE_LEVELS,
|
|
390
|
+
verificationNeed === 'required' || mode === 'plan_execute' ? 'high' : 'medium',
|
|
391
|
+
),
|
|
339
392
|
};
|
|
340
393
|
}
|
|
341
394
|
|
|
@@ -483,6 +536,7 @@ function buildPlanPrompt(analysis, capabilityHealth) {
|
|
|
483
536
|
`Task goal: ${taskGoal}`,
|
|
484
537
|
formatExistingSuccessCriteriaLine(analysis.success_criteria),
|
|
485
538
|
formatSuggestedToolsFromAnalysisLine(analysis.suggested_tools),
|
|
539
|
+
`Autonomy: complexity=${analysis.complexity || 'standard'}, autonomy_level=${analysis.autonomy_level || 'normal'}, progress_update_policy=${analysis.progress_update_policy || 'optional'}, parallel_work=${analysis.parallel_work === true}, completion_confidence_required=${analysis.completion_confidence_required || 'medium'}`,
|
|
486
540
|
], PLAN_SCHEMA_EXAMPLE);
|
|
487
541
|
}
|
|
488
542
|
|
|
@@ -494,6 +548,7 @@ function buildExecutionGuidance({ analysis, plan = null, capabilityHealth }) {
|
|
|
494
548
|
analysis.suggested_tools?.length
|
|
495
549
|
? `Advisory tool suggestions: ${analysis.suggested_tools.join(', ')}`
|
|
496
550
|
: '',
|
|
551
|
+
`Autonomy contract: complexity=${analysis.complexity || 'standard'}; autonomy_level=${analysis.autonomy_level || 'normal'}; progress_update_policy=${analysis.progress_update_policy || 'optional'}; parallel_work=${analysis.parallel_work === true}; completion_confidence_required=${analysis.completion_confidence_required || 'medium'}.`,
|
|
497
552
|
capabilityHealth ? `Capability health:\n${capabilityHealth}` : '',
|
|
498
553
|
];
|
|
499
554
|
|
|
@@ -512,6 +567,7 @@ function buildVerifierPrompt({ analysis, toolExecutionSummary, evidenceSources,
|
|
|
512
567
|
...VERIFIER_PROMPT_INSTRUCTIONS,
|
|
513
568
|
`Freshness risk: ${analysis.freshness_risk}`,
|
|
514
569
|
`Verification need: ${analysis.verification_need}`,
|
|
570
|
+
`Completion confidence required: ${analysis.completion_confidence_required || 'medium'}`,
|
|
515
571
|
formatEvidenceSourcesLine(evidenceSources),
|
|
516
572
|
toolExecutionSummary ? `Execution evidence:\n${toolExecutionSummary}` : '',
|
|
517
573
|
`Draft final reply:\n${finalReply || '(empty)'}`,
|
|
@@ -1289,7 +1289,7 @@ function getAvailableTools(app, options = {}) {
|
|
|
1289
1289
|
// mechanism and gives the AI real agency over when it's finished.
|
|
1290
1290
|
tools.push({
|
|
1291
1291
|
name: 'task_complete',
|
|
1292
|
-
description: 'Signal that the task is fully complete and provide the final response. Call this exactly once when all steps are done and you have a complete answer ready. Do NOT call it if you still have work to do.',
|
|
1292
|
+
description: 'Signal that the task is fully complete and provide the final response. Call this exactly once when all steps are done and you have a complete answer ready. Do NOT call it if you still have work to do, unverified claims, unresolved tool failures, or confidence below the current run requirement.',
|
|
1293
1293
|
parameters: {
|
|
1294
1294
|
type: 'object',
|
|
1295
1295
|
properties: {
|
|
@@ -1300,10 +1300,10 @@ function getAvailableTools(app, options = {}) {
|
|
|
1300
1300
|
confidence: {
|
|
1301
1301
|
type: 'string',
|
|
1302
1302
|
enum: ['high', 'medium', 'low'],
|
|
1303
|
-
description: 'How confident are you the task is fully and correctly complete? Use "low"
|
|
1303
|
+
description: 'How confident are you the task is fully and correctly complete? Use "low" only when the final answer is intentionally limited or incomplete; low confidence may be rejected so the run can keep working.'
|
|
1304
1304
|
}
|
|
1305
1305
|
},
|
|
1306
|
-
required: ['message']
|
|
1306
|
+
required: ['message', 'confidence']
|
|
1307
1307
|
}
|
|
1308
1308
|
});
|
|
1309
1309
|
|
|
@@ -129,6 +129,19 @@ async function buildAuthorizedClient(connection) {
|
|
|
129
129
|
credentials = {};
|
|
130
130
|
}
|
|
131
131
|
client.setCredentials(credentials);
|
|
132
|
+
// Capture any token refresh that happens during the request so the new
|
|
133
|
+
// access_token + expiry_date are always available on client.credentials.
|
|
134
|
+
// The library preserves refresh_token internally; this listener just ensures
|
|
135
|
+
// client.credentials stays in sync when refreshes happen inside deep call stacks.
|
|
136
|
+
client.on('tokens', (tokens) => {
|
|
137
|
+
if (tokens.access_token) {
|
|
138
|
+
client.setCredentials({
|
|
139
|
+
...client.credentials,
|
|
140
|
+
...tokens,
|
|
141
|
+
refresh_token: tokens.refresh_token || client.credentials.refresh_token,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
});
|
|
132
145
|
return client;
|
|
133
146
|
}
|
|
134
147
|
|
|
@@ -679,6 +679,11 @@ class IntegrationManager {
|
|
|
679
679
|
userId,
|
|
680
680
|
resolveAgentId(userId, agentId),
|
|
681
681
|
);
|
|
682
|
+
return {
|
|
683
|
+
error: `Your ${provider.label} account connection has expired and needs to be reconnected. Open Official Integrations to reconnect your account.`,
|
|
684
|
+
expired: true,
|
|
685
|
+
connectionId: selection.connection.id,
|
|
686
|
+
};
|
|
682
687
|
}
|
|
683
688
|
return { error: err?.message || 'execution_error' };
|
|
684
689
|
}
|
|
@@ -9,7 +9,7 @@ const {
|
|
|
9
9
|
} = require('../provider_config_store');
|
|
10
10
|
const { getConnectionAccessMode } = require('../access');
|
|
11
11
|
const { fetchJson } = require('../oauth_provider');
|
|
12
|
-
const { encryptValue } = require('../secrets');
|
|
12
|
+
const { encryptValue, decryptValue } = require('../secrets');
|
|
13
13
|
|
|
14
14
|
const TRELLO_APP = {
|
|
15
15
|
id: 'trello',
|
|
@@ -732,7 +732,13 @@ function createTrelloProvider() {
|
|
|
732
732
|
return 'Trello: native Trello access is connected in this run with one Trello account for board, list, card, comment, and search tools.';
|
|
733
733
|
},
|
|
734
734
|
async executeTool(toolName, args, connection) {
|
|
735
|
-
|
|
735
|
+
let credentials = {};
|
|
736
|
+
try {
|
|
737
|
+
credentials = JSON.parse(decryptValue(connection.credentials_json || '{}') || '{}');
|
|
738
|
+
} catch {
|
|
739
|
+
credentials = {};
|
|
740
|
+
}
|
|
741
|
+
return executeTrelloTool(toolName, args, { connection, credentials });
|
|
736
742
|
},
|
|
737
743
|
getUserConfig({ userId, agentId }) {
|
|
738
744
|
const normalizedUserId = Number(userId);
|