neoagent 2.5.2-beta.15 → 2.5.2-beta.17

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neoagent",
3
- "version": "2.5.2-beta.15",
3
+ "version": "2.5.2-beta.17",
4
4
  "description": "Proactive personal AI agent with no limits",
5
5
  "license": "AGPL-3.0-only",
6
6
  "main": "server/index.js",
@@ -1 +1 @@
1
- 1d10248cc582c1ba92c1198aac6710a0
1
+ 650df5014c7ce4c65d54bc0b04a490c7
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"77e2e94772b6eb43759e34ed1ad7da4674e19c
37
37
 
38
38
  _flutter.loader.load({
39
39
  serviceWorkerSettings: {
40
- serviceWorkerVersion: "250173635" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
40
+ serviceWorkerVersion: "1231520764" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
41
41
  }
42
42
  });
@@ -134794,7 +134794,7 @@ r===$&&A.b()
134794
134794
  p.push(A.jP(q,A.j9(!1,new A.a_(B.uG,A.d8(new A.cA(B.jt,new A.a7N(r,q),q),q,q),q),!1,B.H,!0),q,q,0,0,0,q))}r=!1
134795
134795
  if(!s.ay)if(!s.ch){r=s.e
134796
134796
  r===$&&A.b()
134797
- r=B.b.u("mqgcr48m-8bfb25e").length!==0&&r.b}if(r){r=s.d
134797
+ r=B.b.u("mqge9i3q-1dd91a5").length!==0&&r.b}if(r){r=s.d
134798
134798
  r===$&&A.b()
134799
134799
  r=r.aP&&!r.ai?84:0
134800
134800
  s=s.e
@@ -140506,7 +140506,7 @@ $S:0}
140506
140506
  A.a_6.prototype={}
140507
140507
  A.SQ.prototype={
140508
140508
  nb(a){var s=this
140509
- if(B.b.u("mqgcr48m-8bfb25e").length===0||s.a!=null)return
140509
+ if(B.b.u("mqge9i3q-1dd91a5").length===0||s.a!=null)return
140510
140510
  s.AU()
140511
140511
  s.a=A.on(B.RH,new A.bc8(s))},
140512
140512
  AU(){var s=0,r=A.l(t.H),q,p=2,o=[],n=this,m,l,k,j,i,h,g,f
@@ -140524,7 +140524,7 @@ if(!t.f.b(k)){s=1
140524
140524
  break}i=J.a3(k,"buildId")
140525
140525
  h=i==null?null:B.b.u(J.p(i))
140526
140526
  j=h==null?"":h
140527
- if(J.bi(j)===0||J.d(j,"mqgcr48m-8bfb25e")){s=1
140527
+ if(J.bi(j)===0||J.d(j,"mqge9i3q-1dd91a5")){s=1
140528
140528
  break}n.b=!0
140529
140529
  n.F()
140530
140530
  p=2
@@ -140541,7 +140541,7 @@ case 2:return A.i(o.at(-1),r)}})
140541
140541
  return A.k($async$AU,r)},
140542
140542
  vE(){var s=0,r=A.l(t.H),q,p=2,o=[],n=this,m,l,k,j,i,h,g,f,e,d,c,b,a,a0,a1
140543
140543
  var $async$vE=A.h(function(a2,a3){if(a2===1){o.push(a3)
140544
- s=p}for(;;)switch(s){case 0:if(B.b.u("mqgcr48m-8bfb25e").length===0||n.c){s=1
140544
+ s=p}for(;;)switch(s){case 0:if(B.b.u("mqge9i3q-1dd91a5").length===0||n.c){s=1
140545
140545
  break}n.c=!0
140546
140546
  n.F()
140547
140547
  p=4
@@ -215,8 +215,8 @@ async function extractArtifactsFromResult(toolName, result) {
215
215
  if (value == null) return;
216
216
  if (typeof value === 'string') {
217
217
  const explicit = isExplicitCandidateKey(keyHint, parentKeyHint);
218
- if (explicit && normalizePathOrUri(value)) {
219
- await pushCandidate(value);
218
+ if (explicit) {
219
+ if (normalizePathOrUri(value)) await pushCandidate(value);
220
220
  return;
221
221
  }
222
222
  for (const candidate of scanStringForCandidates(value, { explicit })) {
@@ -47,6 +47,23 @@ async function selectDeliverableWorkflow({
47
47
  tools = [],
48
48
  options = {},
49
49
  }) {
50
+ if (!engine || typeof engine.requestStructuredJson !== 'function') {
51
+ return {
52
+ selection: {
53
+ status: 'standard',
54
+ type: null,
55
+ confidence: 0,
56
+ goal: '',
57
+ requestedOutputs: [],
58
+ supportingCapabilities: [],
59
+ },
60
+ usage: 0,
61
+ raw: '',
62
+ skipped: true,
63
+ reason: 'structured selector unavailable',
64
+ };
65
+ }
66
+
50
67
  const response = await engine.requestStructuredJson({
51
68
  provider,
52
69
  providerName,
@@ -564,9 +564,16 @@ async function runConversation(engine, userId, userMessage, options = {}, _model
564
564
 
565
565
  const runTitle = generateTitle(userMessage);
566
566
  const initialRunMetadata = buildInitialRunMetadata(options);
567
- db.prepare(`INSERT OR REPLACE INTO agent_runs(
567
+ db.prepare(`INSERT INTO agent_runs(
568
568
  id, user_id, agent_id, title, status, trigger_type, trigger_source, model, metadata_json
569
- ) VALUES(?, ?, ?, ?, 'running', ?, ?, ?, ?)`).run(
569
+ ) VALUES(?, ?, ?, ?, 'running', ?, ?, ?, ?)
570
+ ON CONFLICT(id) DO UPDATE SET
571
+ status = 'running',
572
+ model = excluded.model,
573
+ updated_at = datetime('now'),
574
+ completed_at = NULL,
575
+ error = NULL,
576
+ metadata_json = COALESCE(agent_runs.metadata_json, excluded.metadata_json)`).run(
570
577
  runId,
571
578
  userId,
572
579
  agentId,
@@ -762,7 +769,14 @@ async function runConversation(engine, userId, userMessage, options = {}, _model
762
769
  let iteration = 0;
763
770
  let totalTokens = 0;
764
771
  let lastContent = '';
765
- let stepIndex = 0;
772
+ let stepIndex = Number(options.messagingRetryStepOffset || 0);
773
+ if (!Number.isFinite(stepIndex) || stepIndex < 0) {
774
+ stepIndex = 0;
775
+ }
776
+ if (options.messagingAutonomousRetryCount > 0) {
777
+ const existingStep = db.prepare('SELECT COALESCE(MAX(step_index), 0) AS maxStep FROM agent_steps WHERE run_id = ?').get(runId);
778
+ stepIndex = Math.max(stepIndex, Number(existingStep?.maxStep || 0));
779
+ }
766
780
  let failedStepCount = 0;
767
781
  let modelFailureRecoveries = 0;
768
782
  let promptMetrics = {};
@@ -904,54 +918,63 @@ async function runConversation(engine, userId, userMessage, options = {}, _model
904
918
  maxIterations = loopPolicy.maxIterations;
905
919
 
906
920
  if (options.skipDeliverableWorkflow !== true) {
907
- const deliverableSelectionResult = await selectDeliverableWorkflow({
908
- engine,
909
- provider,
910
- providerName,
911
- model,
912
- messages,
913
- tools,
914
- options: { ...options, runId, userId, agentId },
915
- });
916
- totalTokens += deliverableSelectionResult.usage || 0;
917
- const selectedWorkflow = getDeliverableWorkflow(deliverableSelectionResult.selection.type);
918
- if (selectedWorkflow?.canHandle(deliverableSelectionResult.selection)) {
919
- deliverableWorkflow = {
920
- workflow: selectedWorkflow,
921
- selection: deliverableSelectionResult.selection,
922
- request: selectedWorkflow.normalizeRequest({
923
- ...deliverableSelectionResult.selection,
924
- userMessage,
925
- }),
926
- };
927
- deliverablePlan = selectedWorkflow.buildExecutionPlan(deliverableWorkflow.request, {
928
- analysis,
929
- tools,
930
- options,
931
- });
932
- await selectedWorkflow.run(deliverablePlan, {
921
+ try {
922
+ const deliverableSelectionResult = await selectDeliverableWorkflow({
933
923
  engine,
934
- userId,
935
- agentId,
936
- runId,
937
- agentId,
938
- app,
939
- });
940
- engine.persistRunMetadata(runId, {
941
- deliverableWorkflow: {
942
- ...deliverableWorkflow.selection,
943
- plan: deliverablePlan,
944
- },
945
- });
946
- engine.updateRunGoalContract(runId, {
947
- goal: deliverableWorkflow.selection.goal,
924
+ provider,
925
+ providerName,
926
+ model,
927
+ messages,
928
+ tools,
929
+ options: { ...options, runId, userId, agentId },
948
930
  });
949
- engine.recordRunEvent(userId, runId, 'deliverable_workflow_selected', {
950
- type: deliverableWorkflow.selection.type,
951
- confidence: deliverableWorkflow.selection.confidence,
952
- goal: deliverableWorkflow.selection.goal,
953
- requestedOutputs: deliverableWorkflow.selection.requestedOutputs,
931
+ totalTokens += deliverableSelectionResult.usage || 0;
932
+ const selectedWorkflow = getDeliverableWorkflow(deliverableSelectionResult.selection.type);
933
+ if (selectedWorkflow?.canHandle(deliverableSelectionResult.selection)) {
934
+ deliverableWorkflow = {
935
+ workflow: selectedWorkflow,
936
+ selection: deliverableSelectionResult.selection,
937
+ request: selectedWorkflow.normalizeRequest({
938
+ ...deliverableSelectionResult.selection,
939
+ userMessage,
940
+ }),
941
+ };
942
+ deliverablePlan = selectedWorkflow.buildExecutionPlan(deliverableWorkflow.request, {
943
+ analysis,
944
+ tools,
945
+ options,
946
+ });
947
+ await selectedWorkflow.run(deliverablePlan, {
948
+ engine,
949
+ userId,
950
+ agentId,
951
+ runId,
952
+ app,
953
+ });
954
+ engine.persistRunMetadata(runId, {
955
+ deliverableWorkflow: {
956
+ ...deliverableWorkflow.selection,
957
+ plan: deliverablePlan,
958
+ },
959
+ });
960
+ engine.updateRunGoalContract(runId, {
961
+ goal: deliverableWorkflow.selection.goal,
962
+ });
963
+ engine.recordRunEvent(userId, runId, 'deliverable_workflow_selected', {
964
+ type: deliverableWorkflow.selection.type,
965
+ confidence: deliverableWorkflow.selection.confidence,
966
+ goal: deliverableWorkflow.selection.goal,
967
+ requestedOutputs: deliverableWorkflow.selection.requestedOutputs,
968
+ }, { agentId });
969
+ }
970
+ } catch (error) {
971
+ engine.recordRunEvent(userId, runId, 'deliverable_workflow_skipped', {
972
+ reason: summarizeForLog(error?.message || error, 240),
954
973
  }, { agentId });
974
+ messages.push({
975
+ role: 'system',
976
+ content: 'The optional deliverable workflow classifier failed. Continue with the normal agent loop; do not stop or retry the whole run just because this classifier failed.',
977
+ });
955
978
  }
956
979
  }
957
980
 
@@ -2222,6 +2245,8 @@ async function runConversation(engine, userId, userMessage, options = {}, _model
2222
2245
 
2223
2246
  const retryOptions = {
2224
2247
  ...options,
2248
+ runId,
2249
+ messagingRetryStepOffset: stepIndex,
2225
2250
  messagingAutonomousRetryCount: retryCount + 1,
2226
2251
  messagingRetryState: {
2227
2252
  lastFinalMessage: String(runMeta?.lastSentMessage || options?.messagingRetryState?.lastFinalMessage || '').trim(),
@@ -2248,7 +2273,6 @@ async function runConversation(engine, userId, userMessage, options = {}, _model
2248
2273
  ].filter(Boolean).join('\n\n')
2249
2274
  }
2250
2275
  };
2251
- delete retryOptions.runId;
2252
2276
 
2253
2277
  return engine.runWithModel(userId, userMessage, retryOptions, _modelOverride);
2254
2278
  }
@@ -60,11 +60,12 @@ function evaluateProgressLiveness(runMeta, now = Date.now()) {
60
60
 
61
61
  function buildProgressNudge({ stalled = false } = {}) {
62
62
  return [
63
- 'Internal progress check for the active messaging run.',
63
+ 'Mandatory internal progress check for the active messaging run.',
64
64
  stalled
65
65
  ? 'No verified progress has been recorded for the stall threshold.'
66
66
  : 'The originating chat has not received a user-visible update for the progress threshold.',
67
- 'On the next normal agent turn, decide whether to continue silently, send a concise model-authored interim update with send_interim_update, report a real blocker, or finish with the final answer.',
67
+ 'Before starting more tool work, either send a concise model-authored interim update with send_interim_update, report a real blocker, or finish with the final answer.',
68
+ 'Do not continue silently once this check is present unless the immediate next action itself delivers a final answer or explicit no-response decision.',
68
69
  'Do not repeat previous status text and do not treat an interim update as final delivery.',
69
70
  ].join(' ');
70
71
  }
@@ -977,10 +977,15 @@ async function executeGithubTool(toolName, args, auth) {
977
977
  const { owner, repo } = parseOwnerRepo(args.owner_repo);
978
978
  const query = {};
979
979
  if (args.ref) query.ref = String(args.ref);
980
- return await githubApiRequest(auth, {
980
+ const result = await githubApiRequest(auth, {
981
981
  path: `/repos/${owner}/${repo}/contents/${String(args.path || '')}`,
982
982
  query,
983
983
  });
984
+ if (result && result.encoding === 'base64' && typeof result.content === 'string') {
985
+ result.content = Buffer.from(result.content.replace(/\n/g, ''), 'base64').toString('utf8');
986
+ result.encoding = 'utf8';
987
+ }
988
+ return result;
984
989
  }
985
990
 
986
991
  case 'github_create_or_update_file': {