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.
@@ -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" if you had to make assumptions.'
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
- return executeTrelloTool(toolName, args, connection);
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);