neoagent 3.2.1-beta.1 → 3.2.1-beta.11
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 +654 -90
- package/flutter_app/lib/main_chat.dart +118 -739
- package/flutter_app/lib/main_controller.dart +157 -24
- package/flutter_app/lib/main_integrations.dart +607 -8
- package/flutter_app/lib/main_models.dart +7 -2
- package/flutter_app/lib/main_operations.dart +334 -370
- package/flutter_app/lib/main_security.dart +266 -112
- package/flutter_app/lib/main_settings.dart +342 -3
- package/flutter_app/lib/main_shared.dart +14 -11
- package/flutter_app/lib/src/backend_client.dart +97 -0
- 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/landing/index.html +3 -1
- package/lib/manager.js +106 -89
- package/lib/schema_migrations.js +115 -13
- package/package.json +30 -15
- package/runtime/paths.js +49 -5
- package/server/db/database.js +2 -2
- package/server/guest-agent.cli.package.json +13 -0
- package/server/guest_agent.js +85 -40
- package/server/http/middleware.js +24 -0
- package/server/http/routes.js +12 -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 +2 -2
- package/server/public/main.dart.js +81930 -80509
- package/server/routes/admin.js +1 -1
- package/server/routes/android.js +30 -34
- package/server/routes/behavior.js +80 -0
- package/server/routes/browser.js +23 -15
- package/server/routes/desktop.js +18 -1
- package/server/routes/integrations.js +107 -1
- package/server/routes/memory.js +1 -0
- package/server/routes/settings.js +20 -5
- package/server/routes/social_reach.js +12 -3
- package/server/routes/social_video.js +4 -0
- package/server/services/agents/manager.js +1 -1
- package/server/services/ai/capabilityHealth.js +62 -96
- package/server/services/ai/compaction.js +7 -2
- package/server/services/ai/history.js +45 -6
- package/server/services/ai/integrated_tools/http_request.js +8 -0
- package/server/services/ai/loop/agent_engine_core.js +452 -176
- package/server/services/ai/loop/blank_recovery.js +5 -4
- package/server/services/ai/loop/callbacks.js +1 -0
- package/server/services/ai/loop/completion_judge.js +291 -8
- package/server/services/ai/loop/conversation_loop.js +515 -342
- package/server/services/ai/loop/messaging_delivery.js +176 -57
- package/server/services/ai/loop/model_call_guard.js +91 -0
- package/server/services/ai/loop/model_io.js +20 -45
- package/server/services/ai/loop/progress_classification.js +2 -0
- package/server/services/ai/loop/tool_dispatch.js +19 -8
- package/server/services/ai/loopPolicy.js +48 -21
- package/server/services/ai/messagingFallback.js +17 -17
- package/server/services/ai/model_discovery.js +227 -0
- package/server/services/ai/model_failure_cache.js +108 -0
- package/server/services/ai/model_identity.js +71 -0
- package/server/services/ai/models.js +68 -163
- package/server/services/ai/providerRetry.js +17 -59
- package/server/services/ai/provider_selector.js +166 -0
- package/server/services/ai/providers/anthropic.js +2 -2
- package/server/services/ai/providers/claudeCode.js +21 -33
- package/server/services/ai/providers/githubCopilot.js +41 -20
- package/server/services/ai/providers/google.js +135 -97
- package/server/services/ai/providers/grok.js +4 -3
- package/server/services/ai/providers/grokOauth.js +19 -27
- package/server/services/ai/providers/nvidia.js +10 -5
- package/server/services/ai/providers/ollama.js +111 -84
- 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/systemPrompt.js +32 -123
- package/server/services/ai/taskAnalysis.js +104 -11
- package/server/services/ai/toolEvidence.js +256 -29
- package/server/services/ai/tools.js +248 -117
- 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/behavior/config.js +251 -0
- package/server/services/behavior/defaults.js +68 -0
- package/server/services/behavior/delivery.js +176 -0
- package/server/services/behavior/index.js +43 -0
- package/server/services/behavior/model_client.js +35 -0
- package/server/services/behavior/modules/agent_identity.js +37 -0
- package/server/services/behavior/modules/channel_style.js +28 -0
- package/server/services/behavior/modules/index.js +29 -0
- package/server/services/behavior/modules/norms.js +101 -0
- package/server/services/behavior/modules/persona.js +48 -0
- package/server/services/behavior/modules/persona_prompt.js +33 -0
- package/server/services/behavior/modules/social_memory.js +86 -0
- package/server/services/behavior/modules/social_observability.js +94 -0
- package/server/services/behavior/modules/social_signals.js +41 -0
- package/server/services/behavior/modules/theory_of_mind.js +110 -0
- package/server/services/behavior/modules/turn_taking.js +237 -0
- package/server/services/behavior/pipeline.js +285 -0
- package/server/services/behavior/registry.js +78 -0
- package/server/services/behavior/signals.js +107 -0
- package/server/services/behavior/state.js +99 -0
- package/server/services/behavior/system_prompt.js +75 -0
- package/server/services/browser/controller.js +843 -385
- package/server/services/browser/extension/gateway.js +40 -16
- package/server/services/browser/extension/protocol.js +15 -1
- package/server/services/browser/extension/provider.js +71 -47
- package/server/services/browser/extension/registry.js +155 -34
- package/server/services/cli/executor.js +62 -9
- package/server/services/credentials/bitwarden_cli.js +322 -0
- package/server/services/credentials/broker.js +594 -0
- 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/bitwarden/constants.js +14 -0
- package/server/services/integrations/bitwarden/provider.js +197 -0
- package/server/services/integrations/bitwarden/snapshot.js +65 -0
- 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 +159 -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/registry.js +2 -0
- 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 +110 -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 +66 -52
- package/server/services/messaging/access_policy.js +10 -6
- package/server/services/messaging/automation.js +240 -34
- package/server/services/messaging/discord.js +11 -1
- package/server/services/messaging/formatting_guides.js +5 -4
- package/server/services/messaging/http_platforms.js +37 -16
- package/server/services/messaging/inbound_queue.js +143 -28
- package/server/services/messaging/inbound_store.js +257 -0
- package/server/services/messaging/manager.js +344 -51
- package/server/services/messaging/telegram.js +10 -1
- package/server/services/messaging/typing_keepalive.js +5 -2
- package/server/services/messaging/whatsapp.js +33 -14
- 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 +227 -67
- package/server/services/runtime/docker-vm-manager.js +9 -0
- package/server/services/runtime/guest_bootstrap.js +30 -4
- package/server/services/runtime/guest_image.js +43 -12
- package/server/services/runtime/manager.js +77 -23
- package/server/services/runtime/validation.js +7 -6
- package/server/services/security/tool_categories.js +6 -0
- 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 +13 -8
- 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/captions.js +2 -2
- package/server/services/social_video/service.js +343 -68
- 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/message.js +1 -1
- package/server/services/voice/openaiSpeech.js +33 -8
- package/server/services/voice/providers.js +233 -151
- package/server/services/voice/runtime.js +2 -2
- 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/logger.js +19 -0
- package/server/utils/retry.js +107 -0
|
@@ -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,11 +195,204 @@ 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
|
}
|
|
174
202
|
|
|
203
|
+
function clampResearchText(value, maxChars = 220) {
|
|
204
|
+
const text = String(value || '').replace(/\s+/g, ' ').trim();
|
|
205
|
+
if (!text) return '';
|
|
206
|
+
if (text.length <= maxChars) return text;
|
|
207
|
+
return `${text.slice(0, Math.max(0, maxChars - 1)).trimEnd()}…`;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function uniqueResearchTokens(values = [], { limit = 12 } = {}) {
|
|
211
|
+
const seen = new Set();
|
|
212
|
+
const tokens = [];
|
|
213
|
+
for (const value of values) {
|
|
214
|
+
const token = String(value || '').replace(/\s+/g, ' ').trim();
|
|
215
|
+
if (!token) continue;
|
|
216
|
+
const key = token.toLowerCase();
|
|
217
|
+
if (seen.has(key)) continue;
|
|
218
|
+
seen.add(key);
|
|
219
|
+
tokens.push(token);
|
|
220
|
+
if (tokens.length >= limit) break;
|
|
221
|
+
}
|
|
222
|
+
return tokens;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Research targets come from structured task analysis / goal contract only.
|
|
226
|
+
// Do not NLP-extract entity names from free text.
|
|
227
|
+
function collectResearchTargets(analysis = null, goalContext = null) {
|
|
228
|
+
return uniqueResearchTokens([
|
|
229
|
+
...(Array.isArray(analysis?.research_targets) ? analysis.research_targets : []),
|
|
230
|
+
...(Array.isArray(goalContext?.researchTargets) ? goalContext.researchTargets : []),
|
|
231
|
+
], { limit: 8 });
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function resolveResearchIntensity(analysis = null, goalContext = null) {
|
|
235
|
+
const declaredDepth = String(
|
|
236
|
+
analysis?.research_depth
|
|
237
|
+
|| analysis?.researchDepth
|
|
238
|
+
|| '',
|
|
239
|
+
).trim().toLowerCase();
|
|
240
|
+
const declaredTargets = collectResearchTargets(analysis, goalContext);
|
|
241
|
+
if (
|
|
242
|
+
['none', 'light', 'deep'].includes(declaredDepth)
|
|
243
|
+
&& !(declaredDepth === 'none' && declaredTargets.length > 0)
|
|
244
|
+
) {
|
|
245
|
+
return declaredDepth;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const mode = String(analysis?.mode || '').trim().toLowerCase();
|
|
249
|
+
const complexity = String(
|
|
250
|
+
goalContext?.effectiveComplexity
|
|
251
|
+
|| analysis?.complexity
|
|
252
|
+
|| '',
|
|
253
|
+
).trim().toLowerCase();
|
|
254
|
+
const autonomyLevel = String(
|
|
255
|
+
goalContext?.effectiveAutonomyLevel
|
|
256
|
+
|| analysis?.autonomy_level
|
|
257
|
+
|| '',
|
|
258
|
+
).trim().toLowerCase();
|
|
259
|
+
const completionConfidence = String(
|
|
260
|
+
goalContext?.effectiveCompletionConfidence
|
|
261
|
+
|| analysis?.completion_confidence_required
|
|
262
|
+
|| '',
|
|
263
|
+
).trim().toLowerCase();
|
|
264
|
+
const verificationNeed = String(analysis?.verification_need || '').trim().toLowerCase();
|
|
265
|
+
const freshnessRisk = String(analysis?.freshness_risk || '').trim().toLowerCase();
|
|
266
|
+
const planningDepth = String(analysis?.planning_depth || '').trim().toLowerCase();
|
|
267
|
+
const targets = declaredTargets;
|
|
268
|
+
|
|
269
|
+
if (mode === 'direct_answer' && verificationNeed === 'none' && freshnessRisk === 'none') {
|
|
270
|
+
return 'none';
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const needsExternalEvidence = (
|
|
274
|
+
targets.length > 0
|
|
275
|
+
|| freshnessRisk === 'possible'
|
|
276
|
+
|| freshnessRisk === 'high'
|
|
277
|
+
);
|
|
278
|
+
if (!needsExternalEvidence) {
|
|
279
|
+
return 'none';
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const deepSignals = [
|
|
283
|
+
mode === 'plan_execute',
|
|
284
|
+
complexity === 'complex',
|
|
285
|
+
autonomyLevel === 'high',
|
|
286
|
+
completionConfidence === 'high',
|
|
287
|
+
verificationNeed === 'required',
|
|
288
|
+
freshnessRisk === 'high',
|
|
289
|
+
planningDepth === 'deep',
|
|
290
|
+
targets.length >= 2,
|
|
291
|
+
].filter(Boolean).length;
|
|
292
|
+
|
|
293
|
+
if (deepSignals >= 2 || targets.length >= 2 || verificationNeed === 'required' || freshnessRisk === 'high') {
|
|
294
|
+
return 'deep';
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return 'light';
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function isSuccessfulResearchExecution(item = {}) {
|
|
301
|
+
if (!item || item.ok !== true) return false;
|
|
302
|
+
if (!isSubstantiveProgressToolName(item.toolName)) return false;
|
|
303
|
+
if (item.evidenceSource === 'messaging') return false;
|
|
304
|
+
return Boolean(item.evidenceRelevant || item.dependsOnOutput || item.stateChanged);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function selectResearchEvidenceCandidates(toolExecutions = [], maxItems = 80) {
|
|
308
|
+
const candidates = (Array.isArray(toolExecutions) ? toolExecutions : [])
|
|
309
|
+
.map((execution, index) => ({ execution, evidenceIndex: index + 1 }))
|
|
310
|
+
.filter(({ execution }) => isSuccessfulResearchExecution(execution));
|
|
311
|
+
if (candidates.length <= maxItems) return candidates;
|
|
312
|
+
|
|
313
|
+
const firstCount = Math.floor(maxItems / 4);
|
|
314
|
+
return [
|
|
315
|
+
...candidates.slice(0, firstCount),
|
|
316
|
+
...candidates.slice(-(maxItems - firstCount)),
|
|
317
|
+
];
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function summarizeResearchEvidenceCatalog(toolExecutions = [], maxItems = 80) {
|
|
321
|
+
return selectResearchEvidenceCandidates(toolExecutions, maxItems)
|
|
322
|
+
.map(({ execution, evidenceIndex }) => (
|
|
323
|
+
`E${evidenceIndex}. ${execution.toolName} [${execution.evidenceSource || 'tool'}] :: ${clampRunContext(execution.summary || '', 160)}`
|
|
324
|
+
))
|
|
325
|
+
.join('\n');
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function researchExecutionSignature(execution = {}) {
|
|
329
|
+
return JSON.stringify([
|
|
330
|
+
String(execution.toolName || '').trim(),
|
|
331
|
+
execution.input && typeof execution.input === 'object' ? execution.input : {},
|
|
332
|
+
]);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function assessResearchAdequacy({
|
|
336
|
+
analysis = null,
|
|
337
|
+
goalContext = null,
|
|
338
|
+
toolExecutions = [],
|
|
339
|
+
} = {}) {
|
|
340
|
+
const intensity = resolveResearchIntensity(analysis, goalContext);
|
|
341
|
+
const targets = collectResearchTargets(analysis, goalContext);
|
|
342
|
+
|
|
343
|
+
const successful = (Array.isArray(toolExecutions) ? toolExecutions : [])
|
|
344
|
+
.filter(isSuccessfulResearchExecution);
|
|
345
|
+
const uniqueEvidenceCandidateCount = new Set(
|
|
346
|
+
successful.map((item) => researchExecutionSignature(item)),
|
|
347
|
+
).size;
|
|
348
|
+
const structurallyReady = intensity === 'none' || uniqueEvidenceCandidateCount > 0;
|
|
349
|
+
const missing = structurallyReady
|
|
350
|
+
? []
|
|
351
|
+
: ['No successful source-bearing tool evidence is available for semantic review.'];
|
|
352
|
+
const nextActions = [];
|
|
353
|
+
if (!structurallyReady) {
|
|
354
|
+
nextActions.push('Gather source-backed evidence before requesting completion.');
|
|
355
|
+
} else if (intensity !== 'none') {
|
|
356
|
+
nextActions.push('Have the completion judge map each requested target to concrete evidence entries and assess source quality.');
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
return {
|
|
360
|
+
intensity,
|
|
361
|
+
adequate: structurallyReady,
|
|
362
|
+
structurallyReady,
|
|
363
|
+
semanticReviewRequired: intensity !== 'none',
|
|
364
|
+
evidenceCandidateCount: successful.length,
|
|
365
|
+
uniqueEvidenceCandidateCount,
|
|
366
|
+
targets,
|
|
367
|
+
coveredTargets: [],
|
|
368
|
+
primaryCoveredTargets: [],
|
|
369
|
+
uncoveredTargets: intensity === 'none' ? [] : targets,
|
|
370
|
+
primaryUncoveredTargets: intensity === 'none' ? [] : targets,
|
|
371
|
+
missing,
|
|
372
|
+
nextActions,
|
|
373
|
+
reason: structurallyReady
|
|
374
|
+
? (intensity === 'none'
|
|
375
|
+
? 'No research burden for this run.'
|
|
376
|
+
: 'Source candidates exist; the AI completion judge must still validate target coverage and source quality.')
|
|
377
|
+
: clampResearchText(missing.join(' ') || 'Research evidence is still incomplete.', 320),
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
function formatResearchAdequacyGuidance(assessment = null) {
|
|
382
|
+
if (!assessment || assessment.intensity === 'none') return '';
|
|
383
|
+
const lines = [
|
|
384
|
+
assessment.structurallyReady
|
|
385
|
+
? 'Research self-check: source candidates exist, but semantic target coverage is not inferred from tool names, arguments, or token overlap.'
|
|
386
|
+
: 'Research self-check: no successful source evidence is available yet.',
|
|
387
|
+
assessment.reason ? `Gap: ${assessment.reason}` : '',
|
|
388
|
+
assessment.nextActions?.length
|
|
389
|
+
? `Next safe steps:\n- ${assessment.nextActions.join('\n- ')}`
|
|
390
|
+
: '',
|
|
391
|
+
'The completion judge must explicitly map every requested target to supporting evidence and judge whether that evidence is primary, secondary, or merely contextual.',
|
|
392
|
+
];
|
|
393
|
+
return lines.filter(Boolean).join('\n');
|
|
394
|
+
}
|
|
395
|
+
|
|
175
396
|
function isSubstantiveProgressEvidence(item = {}) {
|
|
176
397
|
if (!isSubstantiveProgressToolName(item.toolName)) return false;
|
|
177
398
|
if (item.evidenceSource === 'messaging') return false;
|
|
@@ -246,12 +467,18 @@ function buildAutonomousRecoveryContext({ err, toolExecutions = [], tools = [],
|
|
|
246
467
|
module.exports = {
|
|
247
468
|
classifyToolExecution,
|
|
248
469
|
deriveEvidenceSource,
|
|
470
|
+
assessResearchAdequacy,
|
|
471
|
+
formatResearchAdequacyGuidance,
|
|
249
472
|
gatheredNewEvidence,
|
|
250
473
|
isSubstantiveProgressEvidence,
|
|
251
474
|
isSubstantiveProgressToolName,
|
|
475
|
+
resolveResearchIntensity,
|
|
476
|
+
selectResearchEvidenceCandidates,
|
|
477
|
+
summarizeResearchEvidenceCatalog,
|
|
252
478
|
summarizeProgressToolExecutions,
|
|
253
479
|
summarizeToolExecutions,
|
|
254
480
|
summarizeAvailableTools,
|
|
255
481
|
inferToolFailureMessage,
|
|
256
482
|
buildAutonomousRecoveryContext,
|
|
483
|
+
resolveDeclaredToolAccess,
|
|
257
484
|
};
|