neoagent 3.2.1-beta.2 → 3.2.1-beta.3
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/extensions/chrome-browser/background.mjs +318 -88
- package/extensions/chrome-browser/http.mjs +136 -0
- package/extensions/chrome-browser/protocol.mjs +511 -89
- package/flutter_app/lib/main_chat.dart +118 -739
- package/flutter_app/lib/main_controller.dart +29 -20
- package/flutter_app/lib/main_models.dart +3 -0
- package/flutter_app/lib/main_operations.dart +334 -321
- package/flutter_app/lib/main_settings.dart +4 -3
- package/flutter_app/lib/main_shared.dart +14 -11
- package/flutter_app/lib/src/desktop_companion_actions.dart +185 -31
- package/flutter_app/lib/src/desktop_companion_io.dart +319 -86
- package/flutter_app/windows/runner/flutter_window.cpp +143 -32
- package/lib/manager.js +106 -89
- package/lib/schema_migrations.js +67 -13
- package/package.json +20 -13
- package/runtime/paths.js +49 -5
- package/server/guest_agent.js +52 -30
- package/server/http/middleware.js +24 -0
- package/server/http/routes.js +4 -6
- 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 +30803 -30805
- package/server/routes/admin.js +1 -1
- package/server/routes/android.js +30 -34
- package/server/routes/browser.js +23 -15
- package/server/routes/desktop.js +18 -1
- package/server/routes/integrations.js +5 -1
- package/server/routes/memory.js +1 -0
- package/server/routes/settings.js +16 -5
- package/server/routes/social_reach.js +12 -3
- package/server/routes/social_video.js +4 -0
- package/server/services/ai/compaction.js +7 -2
- package/server/services/ai/history.js +44 -5
- package/server/services/ai/integrated_tools/http_request.js +8 -0
- package/server/services/ai/loop/agent_engine_core.js +347 -162
- package/server/services/ai/loop/callbacks.js +1 -0
- package/server/services/ai/loop/completion_judge.js +12 -0
- package/server/services/ai/loop/conversation_loop.js +348 -242
- package/server/services/ai/loop/messaging_delivery.js +129 -57
- package/server/services/ai/loop/model_call_guard.js +91 -0
- package/server/services/ai/loop/model_io.js +8 -41
- package/server/services/ai/loop/tool_dispatch.js +19 -8
- package/server/services/ai/loopPolicy.js +24 -19
- package/server/services/ai/model_discovery.js +227 -0
- package/server/services/ai/model_identity.js +71 -0
- package/server/services/ai/models.js +67 -162
- package/server/services/ai/providerRetry.js +17 -59
- package/server/services/ai/provider_selector.js +111 -0
- package/server/services/ai/providers/anthropic.js +2 -2
- package/server/services/ai/providers/claudeCode.js +15 -28
- package/server/services/ai/providers/githubCopilot.js +36 -16
- package/server/services/ai/providers/google.js +23 -5
- package/server/services/ai/providers/grok.js +4 -3
- package/server/services/ai/providers/grokOauth.js +13 -22
- package/server/services/ai/providers/nvidia.js +10 -5
- package/server/services/ai/providers/ollama.js +102 -82
- package/server/services/ai/providers/ollama_stream.js +142 -0
- package/server/services/ai/providers/openai.js +39 -5
- package/server/services/ai/providers/openaiCodex.js +11 -4
- package/server/services/ai/providers/openrouter.js +29 -7
- package/server/services/ai/providers/provider_error.js +36 -0
- package/server/services/ai/settings.js +26 -2
- package/server/services/ai/taskAnalysis.js +5 -1
- package/server/services/ai/terminal_reply.js +45 -0
- package/server/services/ai/toolEvidence.js +58 -29
- package/server/services/ai/tools.js +124 -111
- package/server/services/android/controller.js +770 -237
- package/server/services/android/process.js +140 -0
- package/server/services/android/sdk_download.js +143 -0
- package/server/services/android/uia.js +6 -5
- package/server/services/artifacts/store.js +24 -0
- package/server/services/browser/controller.js +736 -385
- package/server/services/browser/extension/gateway.js +40 -16
- package/server/services/browser/extension/protocol.js +12 -1
- package/server/services/browser/extension/provider.js +59 -47
- package/server/services/browser/extension/registry.js +155 -34
- package/server/services/cli/executor.js +62 -9
- package/server/services/desktop/gateway.js +41 -4
- package/server/services/desktop/protocol.js +3 -0
- package/server/services/desktop/provider.js +39 -42
- package/server/services/desktop/registry.js +137 -52
- package/server/services/integrations/figma/provider.js +78 -12
- package/server/services/integrations/github/common.js +11 -6
- package/server/services/integrations/github/provider.js +52 -53
- package/server/services/integrations/google/provider.js +55 -19
- package/server/services/integrations/home_assistant/network.js +17 -20
- package/server/services/integrations/home_assistant/provider.js +7 -5
- package/server/services/integrations/home_assistant/tools.js +17 -5
- package/server/services/integrations/http.js +51 -0
- package/server/services/integrations/manager.js +158 -53
- package/server/services/integrations/microsoft/provider.js +80 -13
- package/server/services/integrations/neoarchive/provider.js +55 -29
- package/server/services/integrations/neorecall/client.js +17 -10
- package/server/services/integrations/neorecall/provider.js +20 -11
- package/server/services/integrations/notion/provider.js +16 -13
- package/server/services/integrations/oauth_provider.js +115 -51
- package/server/services/integrations/slack/provider.js +98 -9
- package/server/services/integrations/spotify/provider.js +67 -71
- package/server/services/integrations/trello/provider.js +21 -7
- package/server/services/integrations/weather/provider.js +18 -12
- package/server/services/integrations/whatsapp/provider.js +76 -16
- package/server/services/manager.js +87 -1
- package/server/services/memory/embedding_index.js +20 -8
- package/server/services/memory/embeddings.js +151 -90
- package/server/services/memory/ingestion.js +50 -9
- package/server/services/memory/ingestion_documents.js +13 -3
- package/server/services/memory/manager.js +52 -19
- package/server/services/messaging/automation.js +84 -9
- package/server/services/messaging/http_platforms.js +33 -13
- package/server/services/messaging/inbound_queue.js +78 -24
- package/server/services/messaging/inbound_store.js +224 -0
- package/server/services/messaging/manager.js +326 -51
- package/server/services/messaging/typing_keepalive.js +5 -2
- package/server/services/network/http.js +210 -0
- package/server/services/network/safe_request.js +307 -0
- package/server/services/runtime/backends/local-vm.js +214 -66
- package/server/services/runtime/manager.js +17 -12
- package/server/services/social_reach/channels/github.js +10 -4
- package/server/services/social_reach/channels/reddit.js +4 -4
- package/server/services/social_reach/channels/rss.js +2 -2
- package/server/services/social_reach/channels/social_video.js +12 -7
- package/server/services/social_reach/channels/v2ex.js +21 -8
- package/server/services/social_reach/channels/x.js +2 -2
- package/server/services/social_reach/channels/xueqiu.js +5 -5
- package/server/services/social_reach/service.js +9 -6
- package/server/services/social_reach/utils.js +65 -14
- package/server/services/social_video/service.js +160 -50
- package/server/services/tasks/integration_runtime.js +18 -8
- package/server/services/tasks/runtime.js +39 -4
- package/server/services/voice/agentBridge.js +17 -4
- package/server/services/voice/bufferedLiveRelayAdapter.js +5 -0
- package/server/services/voice/liveSession.js +31 -0
- package/server/services/voice/openaiSpeech.js +33 -8
- package/server/services/voice/providers.js +233 -151
- package/server/services/voice/runtimeManager.js +118 -20
- package/server/services/voice/turnRunner.js +6 -0
- package/server/services/wearable/firmware_manifest.js +51 -13
- package/server/services/wearable/service.js +1 -0
- package/server/utils/abort.js +96 -0
- package/server/utils/cloud-security.js +110 -3
- package/server/utils/files.js +31 -0
- package/server/utils/image_payload.js +95 -0
- package/server/utils/retry.js +107 -0
|
@@ -17,6 +17,7 @@ const TASK_ANALYSIS_CONFIDENCE_DEFAULT = 0.55;
|
|
|
17
17
|
const VERIFICATION_CONFIDENCE_VERIFIED = 0.85;
|
|
18
18
|
const VERIFICATION_CONFIDENCE_DEFAULT = 0.5;
|
|
19
19
|
const JSON_ONLY_RESPONSE_RULE = 'Return JSON only. No markdown, no prose, no code fences.';
|
|
20
|
+
const { isDeferredWorkReply } = require('./terminal_reply');
|
|
20
21
|
const ANALYSIS_SCHEMA_EXAMPLE = {
|
|
21
22
|
mode: 'execute',
|
|
22
23
|
needs_verification: true,
|
|
@@ -256,7 +257,10 @@ function isDirectAnswerEligibleAnalysis(analysis) {
|
|
|
256
257
|
planningDepth: analysis.planning_depth,
|
|
257
258
|
});
|
|
258
259
|
|
|
259
|
-
return promotedMode === 'direct_answer'
|
|
260
|
+
return promotedMode === 'direct_answer'
|
|
261
|
+
&& !analysis.needs_subagents
|
|
262
|
+
&& Boolean(draftReply)
|
|
263
|
+
&& !isDeferredWorkReply(draftReply);
|
|
260
264
|
}
|
|
261
265
|
|
|
262
266
|
function extractJsonCandidate(text) {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function normalizeReply(content) {
|
|
4
|
+
return String(content || '')
|
|
5
|
+
.replace(/[\u2018\u2019]/g, "'")
|
|
6
|
+
.replace(/^[\s>*_`#-]+/, '')
|
|
7
|
+
.replace(/\s+/g, ' ')
|
|
8
|
+
.trim()
|
|
9
|
+
.toLowerCase();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function hasExternalBlocker(text) {
|
|
13
|
+
return /\b(?:blocked|cannot|can't|could not|couldn't|unable to|do not have access|don't have access|missing (?:access|credentials|permission|information)|need you to|requires? your|waiting for your|please (?:provide|send|choose|confirm|authorize|approve))\b/.test(text);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Detect replies that only announce or promise work which has not happened yet.
|
|
18
|
+
* This is intentionally conservative and supplements the model completion judge;
|
|
19
|
+
* it is a deterministic last line of defence against terminating after a status
|
|
20
|
+
* phrase such as "I'm working on it" or "let me check".
|
|
21
|
+
*/
|
|
22
|
+
function isDeferredWorkReply(content) {
|
|
23
|
+
const text = normalizeReply(content);
|
|
24
|
+
if (!text || hasExternalBlocker(text)) return false;
|
|
25
|
+
|
|
26
|
+
const acknowledgement = '(?:(?:sure|okay|ok|alright|absolutely|of course|got it|understood)[,.!]?\\s+)?';
|
|
27
|
+
const taskTarget = '(?:it|this|that|your\\s+(?:request|task|issue)|the\\s+(?:request|task|issue|problem|code|logs?|repository|repo|build|tests?))';
|
|
28
|
+
const activeWork = `(?:working\\s+(?:on|through)\\s+${taskTarget}|checking(?:\\s+${taskTarget})?|looking\\s+(?:into|at)\\s+${taskTarget}|investigating\\s+${taskTarget}|reviewing\\s+${taskTarget}|researching\\s+${taskTarget}|testing\\s+${taskTarget}|debugging\\s+${taskTarget}|running\\s+${taskTarget}|processing\\s+${taskTarget}|handling\\s+${taskTarget}|starting\\s+${taskTarget}|continuing\\s+${taskTarget})`;
|
|
29
|
+
const promisedWork = '(?:check|look\\s+into|investigate|review|research|test|debug|run|work\\s+on|handle|start|continue|fix|send|create|update|delete|install|restart|deploy|publish|do\\s+that|take\\s+care\\s+of)';
|
|
30
|
+
const patterns = [
|
|
31
|
+
new RegExp(`^${acknowledgement}i(?:'m| am)\\s+(?:(?:still|currently|now|already)\\s+)?${activeWork}\\b`),
|
|
32
|
+
new RegExp(`^${acknowledgement}i(?:'ll| will)\\s+(?:now\\s+)?${promisedWork}\\b`),
|
|
33
|
+
new RegExp(`^${acknowledgement}(?:let me|allow me to)\\s+${promisedWork}\\b`),
|
|
34
|
+
new RegExp(`^${acknowledgement}(?:i(?:'m| am)\\s+going to)\\s+${promisedWork}\\b`),
|
|
35
|
+
/^(?:(?:please )?give me\s+(?:(?:a|one|another)\s+)?(?:moment|minute|bit)|hang tight|please wait|one moment|bear with me)\b/,
|
|
36
|
+
/^(?:working on it|checking now|on it)[.!…]*$/,
|
|
37
|
+
/\bi(?:'ll| will)\s+(?:get back to you|update you|report back|let you know|keep you posted)\b/,
|
|
38
|
+
/\b(?:i(?:'ll| will)\s+follow up|stay tuned)\b/,
|
|
39
|
+
];
|
|
40
|
+
return patterns.some((pattern) => pattern.test(text));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = {
|
|
44
|
+
isDeferredWorkReply,
|
|
45
|
+
};
|
|
@@ -34,30 +34,50 @@ const EVIDENCE_SOURCE_RULES = [
|
|
|
34
34
|
{ source: 'subagent', match: (name) => name.includes('subagent') },
|
|
35
35
|
];
|
|
36
36
|
|
|
37
|
+
const STATE_CHANGING_DEVICE_TOOLS = new Set([
|
|
38
|
+
'android_install_apk',
|
|
39
|
+
'android_long_press',
|
|
40
|
+
'android_open_app',
|
|
41
|
+
'android_open_intent',
|
|
42
|
+
'android_press_key',
|
|
43
|
+
'android_start_emulator',
|
|
44
|
+
'android_stop_emulator',
|
|
45
|
+
'android_swipe',
|
|
46
|
+
'android_tap',
|
|
47
|
+
'android_type',
|
|
48
|
+
'desktop_click',
|
|
49
|
+
'desktop_drag',
|
|
50
|
+
'desktop_launch_app',
|
|
51
|
+
'desktop_press_key',
|
|
52
|
+
'desktop_scroll',
|
|
53
|
+
'desktop_select_device',
|
|
54
|
+
'desktop_type',
|
|
55
|
+
]);
|
|
56
|
+
|
|
37
57
|
function deriveEvidenceSource(name) {
|
|
38
58
|
const rule = EVIDENCE_SOURCE_RULES.find((entry) => entry.match(name));
|
|
39
59
|
return rule ? rule.source : 'tool';
|
|
40
60
|
}
|
|
41
61
|
|
|
42
|
-
function
|
|
62
|
+
function resolveDeclaredToolAccess(toolDefinition, toolArgs = {}) {
|
|
63
|
+
const access = String(toolDefinition?.access || '').trim().toLowerCase();
|
|
64
|
+
if (access === 'read' || access === 'write') return access;
|
|
65
|
+
if (access !== 'dynamic_http_method') return null;
|
|
66
|
+
|
|
67
|
+
const method = String(toolArgs?.method || toolArgs?.http_method || 'GET')
|
|
68
|
+
.trim()
|
|
69
|
+
.toUpperCase();
|
|
70
|
+
return ['GET', 'HEAD', 'OPTIONS'].includes(method) ? 'read' : 'write';
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function classifyToolExecution(
|
|
74
|
+
toolName,
|
|
75
|
+
toolArgs = {},
|
|
76
|
+
result,
|
|
77
|
+
errorMessage = '',
|
|
78
|
+
toolDefinition = null,
|
|
79
|
+
) {
|
|
43
80
|
const name = String(toolName || '');
|
|
44
|
-
const evidenceRelevantPrefixes = ['browser_', 'android_'];
|
|
45
|
-
const evidenceRelevantExact = new Set([
|
|
46
|
-
'web_search',
|
|
47
|
-
'http_request',
|
|
48
|
-
'read_file',
|
|
49
|
-
'read_files',
|
|
50
|
-
'search_files',
|
|
51
|
-
'list_directory',
|
|
52
|
-
'code_navigate',
|
|
53
|
-
'query_structured_data',
|
|
54
|
-
'session_search',
|
|
55
|
-
'memory_recall',
|
|
56
|
-
'analyze_image',
|
|
57
|
-
'read_health_data',
|
|
58
|
-
'list_tasks',
|
|
59
|
-
'wait_subagent',
|
|
60
|
-
]);
|
|
61
81
|
const stateChangingExact = new Set([
|
|
62
82
|
'execute_command',
|
|
63
83
|
'write_file',
|
|
@@ -79,22 +99,30 @@ function classifyToolExecution(toolName, toolArgs = {}, result, errorMessage = '
|
|
|
79
99
|
'mcp_add_server',
|
|
80
100
|
'mcp_remove_server',
|
|
81
101
|
'spawn_subagent',
|
|
102
|
+
'delegate_to_agent',
|
|
82
103
|
'cancel_subagent',
|
|
83
104
|
]);
|
|
84
105
|
|
|
85
|
-
const
|
|
106
|
+
const declaredAccess = resolveDeclaredToolAccess(toolDefinition, toolArgs);
|
|
107
|
+
const evidenceSource = declaredAccess ? 'integration' : deriveEvidenceSource(name);
|
|
86
108
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
)
|
|
109
|
+
// Any successful, substantive tool result can advance the run. This default
|
|
110
|
+
// is deliberate: MCP, skills, and newly added integrations must not become
|
|
111
|
+
// invisible to the churn guard just because their names were not added to a
|
|
112
|
+
// central allow-list. Repetition detection still rejects unchanged retries.
|
|
113
|
+
const evidenceRelevant = isSubstantiveProgressToolName(name);
|
|
114
|
+
let directStateChange;
|
|
115
|
+
if (name === 'execute_command' || name === 'android_shell') {
|
|
116
|
+
directStateChange = !isClearlyReadOnlyShellCommand(toolArgs?.command || '');
|
|
117
|
+
} else {
|
|
118
|
+
directStateChange = declaredAccess === 'write'
|
|
119
|
+
|| STATE_CHANGING_DEVICE_TOOLS.has(name)
|
|
120
|
+
|| stateChangingExact.has(name);
|
|
121
|
+
}
|
|
122
|
+
const stateChanged = directStateChange
|
|
94
123
|
|| (name.startsWith('github_') && isProgressToolCall(name, toolArgs))
|
|
95
124
|
|| (name === 'http_request' && isProgressToolCall(name, toolArgs))
|
|
96
|
-
||
|
|
97
|
-
|| ['browser_click', 'browser_type', 'browser_evaluate'].includes(name);
|
|
125
|
+
|| ['browser_click', 'browser_evaluate', 'browser_navigate', 'browser_type'].includes(name);
|
|
98
126
|
|
|
99
127
|
let normalizedError = String(errorMessage || result?.error || '').trim();
|
|
100
128
|
if (!normalizedError && name === 'execute_command' && result && typeof result === 'object') {
|
|
@@ -167,7 +195,7 @@ function gatheredNewEvidence(execution, repetitionObservation = null) {
|
|
|
167
195
|
function isSubstantiveProgressToolName(toolName = '') {
|
|
168
196
|
const name = String(toolName || '').trim();
|
|
169
197
|
if (!name) return false;
|
|
170
|
-
if (name === 'send_message' || name === 'send_interim_update' || name === 'make_call') return false;
|
|
198
|
+
if (name === 'send_message' || name === 'send_interim_update' || name === 'make_call' || name === 'notify_user') return false;
|
|
171
199
|
if (name === 'think' || name === 'activate_tools' || name === 'task_complete') return false;
|
|
172
200
|
return true;
|
|
173
201
|
}
|
|
@@ -254,4 +282,5 @@ module.exports = {
|
|
|
254
282
|
summarizeAvailableTools,
|
|
255
283
|
inferToolFailureMessage,
|
|
256
284
|
buildAutonomousRecoveryContext,
|
|
285
|
+
resolveDeclaredToolAccess,
|
|
257
286
|
};
|