newmark-agent 0.4.7 → 0.4.8
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/dist/conversation-utility-host.bundle.cjs +287 -18
- package/dist/conversation-utility-host.js +3 -0
- package/dist/core/agent.d.ts +2 -0
- package/dist/core/agent.js +20 -0
- package/dist/core/agentKernelRunner.js +27 -10
- package/dist/core/conversationKernel.d.ts +40 -0
- package/dist/core/conversationKernel.js +219 -8
- package/dist/core/electronUtilityAgentClient.d.ts +8 -0
- package/dist/core/electronUtilityAgentClient.js +5 -1
- package/dist/core/electronUtilityRuntimePool.d.ts +15 -0
- package/dist/core/electronUtilityRuntimePool.js +11 -0
- package/dist/core/toolPolicy.js +3 -0
- package/dist/core/utilityAgentProtocol.d.ts +29 -1
- package/dist/core/utilityHostToolRouter.js +18 -0
- package/dist/core/wslAgentClient.d.ts +8 -0
- package/dist/core/wslAgentClient.js +5 -1
- package/dist/core/wslAgentProtocol.d.ts +18 -1
- package/dist/core/wslAgentRuntimePool.d.ts +15 -0
- package/dist/core/wslAgentRuntimePool.js +11 -0
- package/dist/main.js +193 -7
- package/dist/server.d.ts +32 -1
- package/dist/server.js +157 -35
- package/dist/tools/index.js +46 -1
- package/dist/tools/nativeTools.js +1 -0
- package/dist/wsl-agent-host.bundle.cjs +287 -18
- package/dist/wsl-agent-host.js +3 -0
- package/package.json +2 -2
package/dist/server.js
CHANGED
|
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.runServer = runServer;
|
|
37
|
+
exports.setHostedServerAutomation = setHostedServerAutomation;
|
|
37
38
|
const http = __importStar(require("http"));
|
|
38
39
|
const fs = __importStar(require("fs"));
|
|
39
40
|
const path = __importStar(require("path"));
|
|
@@ -56,6 +57,11 @@ let mobileToken = '';
|
|
|
56
57
|
let appRoot = '';
|
|
57
58
|
const mobileWorkEventSubscribers = new Set();
|
|
58
59
|
const mobileScopedRuntimes = new Map();
|
|
60
|
+
let hostedWorkEventSink = null;
|
|
61
|
+
let unsubscribeHostedWorkEvents = null;
|
|
62
|
+
let hostedConversationUiState;
|
|
63
|
+
let hostedConversationUiAction;
|
|
64
|
+
let hostedConversationPrompt;
|
|
59
65
|
function mobileRuntimeKey(workspaceId, conversationId) {
|
|
60
66
|
return `${String(workspaceId || '')}::${String(conversationId || '')}`;
|
|
61
67
|
}
|
|
@@ -67,6 +73,10 @@ function publishMobileWorkEvent(event) {
|
|
|
67
73
|
catch { /* ignore disconnected mobile listeners */ }
|
|
68
74
|
}
|
|
69
75
|
}
|
|
76
|
+
function publishServerWorkEvent(event) {
|
|
77
|
+
publishMobileWorkEvent(event);
|
|
78
|
+
hostedWorkEventSink?.(event);
|
|
79
|
+
}
|
|
70
80
|
function mobileAuthorized(req) {
|
|
71
81
|
if (!mobileToken)
|
|
72
82
|
return false;
|
|
@@ -837,6 +847,9 @@ async function handleApi(req, res, body) {
|
|
|
837
847
|
mode: agent.mode,
|
|
838
848
|
model: agent.modelSelectionValue(),
|
|
839
849
|
modelLabel: agent.modelLabel(),
|
|
850
|
+
models: agent.allModelNames(),
|
|
851
|
+
providers: (0, config_1.sanitizeProvidersForState)(agent.config.providers()),
|
|
852
|
+
intelligence: agent.intelligence,
|
|
840
853
|
status: agent.status,
|
|
841
854
|
activeConversationId: agent.activeConversationId,
|
|
842
855
|
conversations: agent.listConversationStates(),
|
|
@@ -876,9 +889,18 @@ async function handleApi(req, res, body) {
|
|
|
876
889
|
mobileJson(res, { error: 'Conversation not found in workspace' }, 404);
|
|
877
890
|
return;
|
|
878
891
|
}
|
|
879
|
-
|
|
892
|
+
// GUI conversations normally execute inside isolated runtime pools.
|
|
893
|
+
// Their durable target state can be newer than the hosted main Agent's
|
|
894
|
+
// foreground memory, so workspace-bound mobile reads must hydrate a
|
|
895
|
+
// fresh read-only target Agent from storage.
|
|
896
|
+
const snapshotAgent = ws ? mobileScopedAgent(ws, String(conversationId)) : current;
|
|
897
|
+
const snapshot = snapshotAgent.getConversationSnapshot(String(conversationId), {
|
|
898
|
+
window: windowSize,
|
|
899
|
+
before,
|
|
900
|
+
workspace: ws || undefined,
|
|
901
|
+
});
|
|
880
902
|
// 完整对话信息:workRuns 统一用持久化记录透出(含被中断的构建)
|
|
881
|
-
const persistedRuns =
|
|
903
|
+
const persistedRuns = snapshotAgent.getPersistedConversationWorkRuns(String(conversationId), ws || undefined);
|
|
882
904
|
if (persistedRuns.length)
|
|
883
905
|
snapshot.workRuns = persistedRuns;
|
|
884
906
|
mobileJson(res, snapshot);
|
|
@@ -915,6 +937,36 @@ async function handleApi(req, res, body) {
|
|
|
915
937
|
mobileJson(res, mobileRightSidebarState(agent, ws, conversationId));
|
|
916
938
|
return;
|
|
917
939
|
}
|
|
940
|
+
case '/api/mobile/conversation-ui-state': {
|
|
941
|
+
const workspaceId = url.searchParams.get('workspaceId') || '';
|
|
942
|
+
const conversationId = url.searchParams.get('conversationId') || '';
|
|
943
|
+
const ws = resolveMobileWorkspace(agent, workspaceId);
|
|
944
|
+
if (!ws) {
|
|
945
|
+
mobileJson(res, { error: 'Unknown workspace' }, 404);
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
if (!conversationId || !agent.hasConversationInWorkspace(conversationId, ws)) {
|
|
949
|
+
mobileJson(res, { error: 'Conversation not found in workspace' }, 404);
|
|
950
|
+
return;
|
|
951
|
+
}
|
|
952
|
+
if (hostedConversationUiState) {
|
|
953
|
+
mobileJson(res, await hostedConversationUiState({ workspaceId, conversationId }));
|
|
954
|
+
return;
|
|
955
|
+
}
|
|
956
|
+
const scoped = mobileScopedAgent(ws, conversationId);
|
|
957
|
+
const snapshot = scoped.getConversationSnapshot(conversationId, { workspace: ws, window: 1 });
|
|
958
|
+
mobileJson(res, {
|
|
959
|
+
goal: snapshot.goal,
|
|
960
|
+
flowSelection: snapshot.flowSelection,
|
|
961
|
+
flow: null,
|
|
962
|
+
queued: { steering: [], followUp: [] },
|
|
963
|
+
runtime: null,
|
|
964
|
+
mode: scoped.mode,
|
|
965
|
+
status: scoped.status,
|
|
966
|
+
inputMode: scoped.inputMode,
|
|
967
|
+
});
|
|
968
|
+
return;
|
|
969
|
+
}
|
|
918
970
|
case '/api/mobile/workspace-files': {
|
|
919
971
|
const workspaceId = url.searchParams.get('workspaceId') || '';
|
|
920
972
|
const relativePath = url.searchParams.get('path') || '';
|
|
@@ -1030,6 +1082,52 @@ async function handleApi(req, res, body) {
|
|
|
1030
1082
|
});
|
|
1031
1083
|
return;
|
|
1032
1084
|
}
|
|
1085
|
+
case '/api/mobile/model': {
|
|
1086
|
+
const next = String(JSON.parse(body || '{}').model || '');
|
|
1087
|
+
if (!next) {
|
|
1088
|
+
mobileJson(res, { error: 'Model is required' }, 400);
|
|
1089
|
+
return;
|
|
1090
|
+
}
|
|
1091
|
+
agent.setModel(next);
|
|
1092
|
+
mobileJson(res, {
|
|
1093
|
+
ok: true,
|
|
1094
|
+
model: agent.modelSelectionValue(),
|
|
1095
|
+
modelLabel: agent.modelLabel(),
|
|
1096
|
+
});
|
|
1097
|
+
return;
|
|
1098
|
+
}
|
|
1099
|
+
case '/api/mobile/intelligence': {
|
|
1100
|
+
const tier = String(JSON.parse(body || '{}').tier || 'medium');
|
|
1101
|
+
agent.setIntelligence(tier, true);
|
|
1102
|
+
mobileJson(res, { ok: true, intelligence: agent.intelligence });
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
case '/api/mobile/conversation-ui-action': {
|
|
1106
|
+
const params = JSON.parse(body || '{}');
|
|
1107
|
+
const workspaceId = String(params.workspaceId || '');
|
|
1108
|
+
const conversationId = String(params.conversationId || '');
|
|
1109
|
+
const action = String(params.action || '');
|
|
1110
|
+
const allowed = new Set(['goal_update', 'goal_guide', 'conversation_guide', 'goal_toggle_pause', 'goal_clear', 'flow_pause', 'flow_resume', 'flow_guide', 'conversation_stop', 'input_mode', 'queue_enqueue', 'queue_update', 'queue_delete', 'queue_toggle_pause', 'queue_guide']);
|
|
1111
|
+
if (!workspaceId || !conversationId || !allowed.has(action)) {
|
|
1112
|
+
mobileJson(res, { error: 'workspaceId, conversationId, and a valid action are required' }, 400);
|
|
1113
|
+
return;
|
|
1114
|
+
}
|
|
1115
|
+
const ws = resolveMobileWorkspace(agent, workspaceId);
|
|
1116
|
+
if (!ws) {
|
|
1117
|
+
mobileJson(res, { error: 'Unknown workspace' }, 404);
|
|
1118
|
+
return;
|
|
1119
|
+
}
|
|
1120
|
+
if (!agent.hasConversationInWorkspace(conversationId, ws)) {
|
|
1121
|
+
mobileJson(res, { error: 'Conversation not found in workspace' }, 404);
|
|
1122
|
+
return;
|
|
1123
|
+
}
|
|
1124
|
+
if (!hostedConversationUiAction) {
|
|
1125
|
+
mobileJson(res, { error: 'This action requires the GUI-hosted mobile server' }, 409);
|
|
1126
|
+
return;
|
|
1127
|
+
}
|
|
1128
|
+
mobileJson(res, await hostedConversationUiAction({ workspaceId, conversationId }, action, String(params.value || ''), params));
|
|
1129
|
+
return;
|
|
1130
|
+
}
|
|
1033
1131
|
case '/api/mobile/conversation-rename': {
|
|
1034
1132
|
const params = JSON.parse(body || '{}');
|
|
1035
1133
|
const workspaceId = String(params.workspaceId || '');
|
|
@@ -1144,6 +1242,15 @@ async function handleApi(req, res, body) {
|
|
|
1144
1242
|
requestAgent = mobileScopedAgent(ws, conversationId);
|
|
1145
1243
|
}
|
|
1146
1244
|
}
|
|
1245
|
+
if (hostedConversationPrompt && resolvedWorkspace) {
|
|
1246
|
+
const result = await hostedConversationPrompt({ workspaceId, conversationId }, message, {
|
|
1247
|
+
requestedMode: String(params.requestedMode || ''),
|
|
1248
|
+
goalObjective: String(params.goalObjective || ''),
|
|
1249
|
+
inputMode: String(params.inputMode || ''),
|
|
1250
|
+
});
|
|
1251
|
+
mobileJson(res, { ok: true, conversationId, ...result });
|
|
1252
|
+
return;
|
|
1253
|
+
}
|
|
1147
1254
|
if (requestAgent === agent && params.conversationId)
|
|
1148
1255
|
requestAgent.setConversation(conversationId);
|
|
1149
1256
|
let scopedRuntimeKey = '';
|
|
@@ -1151,7 +1258,7 @@ async function handleApi(req, res, body) {
|
|
|
1151
1258
|
let unsubscribeScoped = null;
|
|
1152
1259
|
if (requestAgent !== agent && requestWorkspace) {
|
|
1153
1260
|
scopedRuntimeKey = mobileRuntimeKey(String(requestWorkspace.id || ''), conversationId);
|
|
1154
|
-
unsubscribeScoped = requestAgent.subscribeWorkEvents(event =>
|
|
1261
|
+
unsubscribeScoped = requestAgent.subscribeWorkEvents(event => publishServerWorkEvent({
|
|
1155
1262
|
...event,
|
|
1156
1263
|
workspaceId: String(requestWorkspace?.id || ''),
|
|
1157
1264
|
conversationId,
|
|
@@ -1302,40 +1409,51 @@ async function handleApi(req, res, body) {
|
|
|
1302
1409
|
jsonResponse(res, { error: e.message }, 500);
|
|
1303
1410
|
}
|
|
1304
1411
|
}
|
|
1305
|
-
function startServer(root) {
|
|
1412
|
+
function startServer(root, options = {}) {
|
|
1306
1413
|
mobileToken = (0, mobilePairing_1.ensureMobileToken)(root);
|
|
1307
1414
|
appRoot = root;
|
|
1308
|
-
agent = new agent_1.Agent(root);
|
|
1415
|
+
agent = options.agent || new agent_1.Agent(root);
|
|
1416
|
+
hostedWorkEventSink = options.onWorkEvent || null;
|
|
1417
|
+
hostedConversationUiState = options.conversationUiState;
|
|
1418
|
+
hostedConversationUiAction = options.conversationUiAction;
|
|
1419
|
+
hostedConversationPrompt = options.conversationPrompt;
|
|
1420
|
+
unsubscribeHostedWorkEvents?.();
|
|
1421
|
+
unsubscribeHostedWorkEvents = options.subscribeWorkEvents?.(publishMobileWorkEvent) || null;
|
|
1309
1422
|
workspaceFileRouter = new workspaceFileRouter_1.WorkspaceFileRouter(() => path.resolve(agent?.workspace.current?.path || root));
|
|
1310
|
-
automation =
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
try {
|
|
1325
|
-
const tokens = await agent.process(prompt);
|
|
1326
|
-
return tokens.map(t => t.text).join('');
|
|
1327
|
-
}
|
|
1328
|
-
finally {
|
|
1423
|
+
automation = options.automation || null;
|
|
1424
|
+
if (!automation && !options.agent)
|
|
1425
|
+
automation = new automation_1.AutomationManager(agent.config, async (prompt, model, item) => {
|
|
1426
|
+
if (!agent)
|
|
1427
|
+
return '';
|
|
1428
|
+
const previousModel = agent.model;
|
|
1429
|
+
const previousWorkspace = agent.workspace.current?.id || agent.workspace.current?.path || '';
|
|
1430
|
+
const previousConversation = agent.activeConversationId;
|
|
1431
|
+
agent.selectWorkspaceFromStorage(item.workspaceId);
|
|
1432
|
+
const conversationId = item.conversationMode === 'existing'
|
|
1433
|
+
? item.conversationId
|
|
1434
|
+
: `automation-${item.id}-${Date.now().toString(36)}`;
|
|
1435
|
+
agent.setConversationFromStorage(conversationId);
|
|
1436
|
+
automation?.update(item.id, { lastConversationId: conversationId });
|
|
1329
1437
|
if (model)
|
|
1330
|
-
agent.setModel(
|
|
1331
|
-
|
|
1332
|
-
agent.
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1438
|
+
agent.setModel(model);
|
|
1439
|
+
try {
|
|
1440
|
+
const tokens = await agent.process(prompt);
|
|
1441
|
+
return tokens.map(t => t.text).join('');
|
|
1442
|
+
}
|
|
1443
|
+
finally {
|
|
1444
|
+
if (model)
|
|
1445
|
+
agent.setModel(previousModel);
|
|
1446
|
+
if (previousWorkspace)
|
|
1447
|
+
agent.selectWorkspaceFromStorage(previousWorkspace);
|
|
1448
|
+
agent.setConversationFromStorage(previousConversation);
|
|
1449
|
+
}
|
|
1450
|
+
});
|
|
1451
|
+
agent.subscribeWorkEvents(publishServerWorkEvent);
|
|
1452
|
+
if (automation) {
|
|
1453
|
+
agent.setAutomationManager(automation);
|
|
1454
|
+
if (!options.automation)
|
|
1455
|
+
automation.start();
|
|
1456
|
+
}
|
|
1339
1457
|
const uiDir = path.join(__dirname, 'ui');
|
|
1340
1458
|
const server = http.createServer(async (req, res) => {
|
|
1341
1459
|
if (req.method === 'OPTIONS') {
|
|
@@ -1388,10 +1506,14 @@ function startServer(root) {
|
|
|
1388
1506
|
}
|
|
1389
1507
|
let hostedServerStarted = false;
|
|
1390
1508
|
/** 托管启动 server(GUI/TUI 内嵌调用;幂等防重入,进程常驻即服务常驻) */
|
|
1391
|
-
function runServer(root) {
|
|
1509
|
+
function runServer(root, options = {}) {
|
|
1392
1510
|
if (hostedServerStarted)
|
|
1393
1511
|
return;
|
|
1394
1512
|
hostedServerStarted = true;
|
|
1395
|
-
startServer(root);
|
|
1513
|
+
startServer(root, options);
|
|
1514
|
+
}
|
|
1515
|
+
/** Attach the GUI-owned automation manager after deferred startup. */
|
|
1516
|
+
function setHostedServerAutomation(manager) {
|
|
1517
|
+
automation = manager;
|
|
1396
1518
|
}
|
|
1397
1519
|
//# sourceMappingURL=server.js.map
|
package/dist/tools/index.js
CHANGED
|
@@ -294,6 +294,13 @@ class ToolExecutor {
|
|
|
294
294
|
max_refs: { type: 'number' },
|
|
295
295
|
attribute: { type: 'string' },
|
|
296
296
|
}, ['action']),
|
|
297
|
+
t('screen_capture', 'Read-only active Windows screenshot available without provisioning or starting full Computer Use. Capture the whole desktop or one visible application. The image is a one-use model input and is deleted immediately; semantic Windows UI objects are returned alongside it.', {
|
|
298
|
+
target: { type: 'string', enum: ['desktop', 'application'], description: 'Capture the whole desktop or one visible application. Defaults to desktop.' },
|
|
299
|
+
app_target: { type: 'string', description: 'For target=application: application title, process name, process id, or window handle.' },
|
|
300
|
+
capture_max_width: { type: 'number', minimum: 320, maximum: 2048, description: 'Maximum ephemeral screenshot width; defaults to 1280. Aspect ratio is preserved and the source is never enlarged.' },
|
|
301
|
+
capture_max_height: { type: 'number', minimum: 240, maximum: 2048, description: 'Maximum ephemeral screenshot height; defaults to 960. Aspect ratio is preserved and the source is never enlarged.' },
|
|
302
|
+
max_chars: { type: 'number', minimum: 1000, maximum: 100000, description: 'Maximum returned semantic UI text characters.' },
|
|
303
|
+
}, []),
|
|
297
304
|
t('computer_use', 'Native Windows desktop control with persistent observation/action helpers. Use observe/app_observe before acting. sequence may perform up to three stable low-risk move/click/scroll/wait/app_activate steps and stops when focus, window, menu, dialog, scene, or risk changes. Vision screenshots remain one-time inputs and are deleted immediately.', {
|
|
298
305
|
action: { type: 'string', enum: ['observe', 'app_list', 'app_observe', 'sequence', 'takeover_start', 'takeover_stop', 'move', 'click', 'scroll', 'type', 'key', 'wait', 'app_activate', 'app_click', 'app_scroll', 'app_type', 'app_key'] },
|
|
299
306
|
capture_max_width: { type: 'number', minimum: 320, maximum: 2048, description: 'For observe/app_observe only. Maximum ephemeral screenshot width; defaults to 1280. Aspect ratio is preserved and the source is never enlarged.' },
|
|
@@ -790,6 +797,44 @@ class ToolExecutor {
|
|
|
790
797
|
result: parsed,
|
|
791
798
|
}, null, 2);
|
|
792
799
|
}
|
|
800
|
+
case 'screen_capture': {
|
|
801
|
+
const target = g('target').toLowerCase() === 'application' ? 'application' : 'desktop';
|
|
802
|
+
if (process.env.NEWMARK_WSL_DISTRO) {
|
|
803
|
+
const result = await (0, wslHostToolBridge_1.requestWindowsHostTool)('screen_capture', args, {
|
|
804
|
+
conversationId: context.conversationId || 'default',
|
|
805
|
+
workspaceId: context.workspaceId || (0, terminalTakeover_1.terminalTakeoverWorkspaceId)(context.workspacePath || wsPath),
|
|
806
|
+
actorId: context.actorId || terminalTakeover_1.ROOT_TERMINAL_ACTOR_ID,
|
|
807
|
+
runtimeKey: browserUseScope(context, wsPath).runtimeKey,
|
|
808
|
+
allowEphemeralVisionImage: context.allowEphemeralVisionImage === true,
|
|
809
|
+
mode: context.mode || 'build',
|
|
810
|
+
}, 120_000, context.signal);
|
|
811
|
+
return typeof result === 'string' ? result : JSON.stringify(result);
|
|
812
|
+
}
|
|
813
|
+
if (process.env.NEWMARK_ISOLATED_RUNTIME === '1') {
|
|
814
|
+
const result = await (0, utilityHostToolBridge_1.requestUtilityHostTool)('screen_capture', args, {
|
|
815
|
+
conversationId: context.conversationId || 'default',
|
|
816
|
+
workspaceId: context.workspaceId || (0, terminalTakeover_1.terminalTakeoverWorkspaceId)(context.workspacePath || wsPath),
|
|
817
|
+
actorId: context.actorId || terminalTakeover_1.ROOT_TERMINAL_ACTOR_ID,
|
|
818
|
+
workspacePath: context.workspacePath || wsPath,
|
|
819
|
+
backend: 'utility',
|
|
820
|
+
mode: context.mode || 'build',
|
|
821
|
+
allowEphemeralVisionImage: context.allowEphemeralVisionImage === true,
|
|
822
|
+
}, 120_000, context.signal);
|
|
823
|
+
return typeof result === 'string' ? result : JSON.stringify(result);
|
|
824
|
+
}
|
|
825
|
+
return await (0, computerUse_1.runComputerUse)({
|
|
826
|
+
action: target === 'application' ? 'app_observe' : 'observe',
|
|
827
|
+
appTarget: g('app_target'),
|
|
828
|
+
windowHandle: target === 'application' ? g('app_target') : '',
|
|
829
|
+
maxChars: Number(args.max_chars || 30000),
|
|
830
|
+
workspacePath: wsPath,
|
|
831
|
+
allowEphemeralVisionImage: context.allowEphemeralVisionImage === true,
|
|
832
|
+
captureMaxWidth: Number(args.capture_max_width),
|
|
833
|
+
captureMaxHeight: Number(args.capture_max_height),
|
|
834
|
+
invocation: context.invocation,
|
|
835
|
+
ownerId: `screen-capture:${computerUseOwner(context, wsPath)}:${String(context.actorId || 'root')}`,
|
|
836
|
+
});
|
|
837
|
+
}
|
|
793
838
|
case 'computer_use': {
|
|
794
839
|
const action = normalizeComputerUseAction(g('action'));
|
|
795
840
|
const owner = `${computerUseOwner(context, wsPath)}:${String(context.actorId || 'root')}`;
|
|
@@ -976,7 +1021,7 @@ class ToolExecutor {
|
|
|
976
1021
|
hostSupportsTool(name) {
|
|
977
1022
|
if (name.startsWith('browser_') && !this.hostProfile.electronBrowser)
|
|
978
1023
|
return false;
|
|
979
|
-
if (name === 'computer_use' && !this.hostProfile.windowsComputerUse)
|
|
1024
|
+
if ((name === 'computer_use' || name === 'screen_capture') && !this.hostProfile.windowsComputerUse)
|
|
980
1025
|
return false;
|
|
981
1026
|
return true;
|
|
982
1027
|
}
|
|
@@ -26,6 +26,7 @@ exports.NATIVE_TOOL_CATALOG = [
|
|
|
26
26
|
{ name: 'browser_reload', label: 'Browser reload', description: 'Reload the built-in browser.', category: 'browser', defaultEnabled: true },
|
|
27
27
|
{ name: 'browser_cdp', label: 'Browser CDP', description: 'Run an advanced Chrome DevTools Protocol command.', category: 'browser', defaultEnabled: true },
|
|
28
28
|
{ name: 'browser_use', label: 'Browser Use', description: 'Observe and control the built-in browser through scoped opaque element refs and structured receipts.', category: 'browser', defaultEnabled: true },
|
|
29
|
+
{ name: 'screen_capture', label: 'Active screenshot', description: 'Capture the Windows desktop or one visible application without starting the full Computer Use control surface.', category: 'desktop', defaultEnabled: true, protected: true, availability: 'mode-scoped' },
|
|
29
30
|
{ name: 'computer_use', label: 'Computer Use', description: 'Observe and control Windows desktop UI with screenshots and semantic objects.', category: 'desktop', defaultEnabled: true },
|
|
30
31
|
{ name: 'image_inspect', label: 'Image inspect', description: 'Crop and magnify images submitted in the current conversation for closer visual inspection.', category: 'core', defaultEnabled: true, protected: true, availability: 'mode-scoped' },
|
|
31
32
|
{ name: 'image_display', label: 'Image display', description: 'Present a workspace PNG/JPEG inside the current Build Block.', category: 'core', defaultEnabled: true, protected: true, availability: 'mode-scoped' },
|