newmark-agent 0.4.5 → 0.4.7
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/assets/app-icon-dark.svg +6 -0
- package/dist/assets/app-icon-dark.svg +6 -0
- package/dist/cli-commands.d.ts +1 -1
- package/dist/cli-commands.js +90 -7
- package/dist/cli-discovery.js +10 -0
- package/dist/conversation-utility-host.bundle.cjs +293 -148
- package/dist/core/agent.d.ts +38 -4
- package/dist/core/agent.js +231 -49
- package/dist/core/agentKernelRunner.d.ts +3 -0
- package/dist/core/agentKernelRunner.js +49 -83
- package/dist/core/config.js +3 -0
- package/dist/core/dshCompatibility.d.ts +23 -6
- package/dist/core/dshCompatibility.js +99 -1
- package/dist/core/installUpdate.d.ts +67 -0
- package/dist/core/installUpdate.js +268 -0
- package/dist/core/mobilePairing.d.ts +47 -0
- package/dist/core/mobilePairing.js +221 -0
- package/dist/core/subagent.d.ts +10 -3
- package/dist/core/subagent.js +23 -8
- package/dist/core/toolPolicy.js +11 -3
- package/dist/launcher.js +14 -11
- package/dist/main.js +64 -3
- package/dist/preload.js +5 -0
- package/dist/providers/chat-completions.adapter.js +6 -2
- package/dist/providers/responses.adapter.js +1 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +721 -3
- package/dist/toolchain/registry-seeder.js +3 -1
- package/dist/tools/index.js +11 -5
- package/dist/tools/nativeTools.js +1 -1
- package/dist/tui/src/adapters/core-runtime-adapter.js +17 -1
- package/dist/tui/src/app.js +41 -0
- package/dist/tui/src/data.js +1 -0
- package/dist/tui/src/render.js +11 -0
- package/dist/tui/src/settings-schema.js +3 -1
- package/dist/tui/src/state.js +21 -1
- package/dist/ui/index.html +530 -101
- package/dist/ui/lucide-sprite.svg +10 -0
- package/dist/wsl-agent-host.bundle.cjs +293 -148
- package/package.json +14 -8
package/dist/core/toolPolicy.js
CHANGED
|
@@ -26,6 +26,10 @@ const MODE_SCOPED_TOOLS = new Set([
|
|
|
26
26
|
'task_read',
|
|
27
27
|
'task_create',
|
|
28
28
|
'question',
|
|
29
|
+
'SubAgent',
|
|
30
|
+
'subagent_create',
|
|
31
|
+
// Legacy runtime alias. It is no longer published to models because its
|
|
32
|
+
// generic name collides with the persistent task checklist.
|
|
29
33
|
'task',
|
|
30
34
|
'subagent_list',
|
|
31
35
|
'subagent_read',
|
|
@@ -59,6 +63,8 @@ const PLAN_READ_ONLY_TOOLS = new Set([
|
|
|
59
63
|
'skill',
|
|
60
64
|
'linked_plan',
|
|
61
65
|
'build_history_query',
|
|
66
|
+
'SubAgent',
|
|
67
|
+
'subagent_create',
|
|
62
68
|
'task',
|
|
63
69
|
'subagent_list',
|
|
64
70
|
'subagent_read',
|
|
@@ -76,9 +82,10 @@ const PLAN_BROWSER_USE_ACTION_SET = new Set(exports.PLAN_BROWSER_USE_ACTIONS);
|
|
|
76
82
|
/**
|
|
77
83
|
* 并发安全工具集合(DSH isConcurrencySafe 语义的 Newmark 落地)。
|
|
78
84
|
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
85
|
+
* 确定性无副作用的只读工具允许与兄弟 tool call 并发执行。`SubAgent` 创建是
|
|
86
|
+
* 唯一允许并发的受控写操作:每个调用只追加一个独立 UUID 记录,真正的 worker
|
|
87
|
+
* 并发由 SubagentManager 的 4/16 槽位及 Build Block 硬上限管理。其他写入、shell、
|
|
88
|
+
* 浏览器交互、子代理发送/关闭等操作仍保持独占串行。缺省保守:不在集合中的
|
|
82
89
|
* 工具一律视为独占。
|
|
83
90
|
*
|
|
84
91
|
* 注意:read/grep/glob/pwd 是同一进程内的内存/文件系统只读,可安全重叠;
|
|
@@ -96,6 +103,7 @@ const CONCURRENCY_SAFE_TOOLS = new Set([
|
|
|
96
103
|
'git_status',
|
|
97
104
|
'file_audit',
|
|
98
105
|
'repo_security_audit',
|
|
106
|
+
'SubAgent',
|
|
99
107
|
]);
|
|
100
108
|
/** 判断一个工具是否可参与并行调度。缺省 false(独占)。
|
|
101
109
|
* 优先看 toolchain registry 推断的 riskLevel('read' 工具天然并发安全,
|
package/dist/launcher.js
CHANGED
|
@@ -312,6 +312,19 @@ if (isGui) {
|
|
|
312
312
|
launchGui();
|
|
313
313
|
}
|
|
314
314
|
else if (isTui) {
|
|
315
|
+
// 远程触及开关开启 → 后端托管启动 mobile server(不阻塞 TUI 其他功能;TUI 退出即随终端托管结束)
|
|
316
|
+
try {
|
|
317
|
+
const { ConfigManager } = require('./core/config');
|
|
318
|
+
const tuiConfig = new ConfigManager(root);
|
|
319
|
+
if (tuiConfig.getBool('remote', 'touch_enabled')) {
|
|
320
|
+
const { runServer } = require('./server');
|
|
321
|
+
runServer(root);
|
|
322
|
+
console.log('[Newmark] mobile server hosted (remote touch enabled)');
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
console.error('[Newmark] TUI hosted mobile server failed:', error instanceof Error ? error.message : String(error));
|
|
327
|
+
}
|
|
315
328
|
const { start } = require('./tui/src/app');
|
|
316
329
|
start({ root, workspacePath: resolveTuiWorkspacePath(args, root), desktopDist: __dirname });
|
|
317
330
|
}
|
|
@@ -363,18 +376,8 @@ else if (isCli || (!isServer && isTerminal())) {
|
|
|
363
376
|
runCli(root);
|
|
364
377
|
}
|
|
365
378
|
else {
|
|
366
|
-
// Server mode - start HTTP server
|
|
379
|
+
// Server mode - start HTTP server(不绑定启动浏览器)
|
|
367
380
|
const { runServer } = require('./server');
|
|
368
381
|
runServer(root);
|
|
369
|
-
if (!args.includes('--no-browser')) {
|
|
370
|
-
const { exec } = require('child_process');
|
|
371
|
-
const port = 47890;
|
|
372
|
-
const cmd = process.platform === 'win32'
|
|
373
|
-
? `start http://localhost:${port}`
|
|
374
|
-
: process.platform === 'darwin'
|
|
375
|
-
? `open http://localhost:${port}`
|
|
376
|
-
: `xdg-open http://localhost:${port}`;
|
|
377
|
-
exec(cmd);
|
|
378
|
-
}
|
|
379
382
|
}
|
|
380
383
|
//# sourceMappingURL=launcher.js.map
|
package/dist/main.js
CHANGED
|
@@ -55,6 +55,7 @@ const cli_discovery_1 = require("./cli-discovery");
|
|
|
55
55
|
const config_1 = require("./core/config");
|
|
56
56
|
const memoryLab_1 = require("./core/memoryLab");
|
|
57
57
|
const installUpdate_1 = require("./core/installUpdate");
|
|
58
|
+
const mobilePairing_1 = require("./core/mobilePairing");
|
|
58
59
|
const terminalTakeover_1 = require("./tools/terminalTakeover");
|
|
59
60
|
const nativeBash_1 = require("./core/nativeBash");
|
|
60
61
|
const nativeTools_1 = require("./tools/nativeTools");
|
|
@@ -419,9 +420,10 @@ function relayFlowAgentWorkEvents(flowAgent, target) {
|
|
|
419
420
|
});
|
|
420
421
|
}
|
|
421
422
|
function themedAppIconPath() {
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
423
|
+
// Fixed black-on-white icon across every theme: the titlebar, taskbar, tray,
|
|
424
|
+
// and Windows executable all share the same dark icon asset.
|
|
425
|
+
const compactPath = path.join(__dirname, 'assets', 'app-icon-dark-64.png');
|
|
426
|
+
return fs.existsSync(compactPath) ? compactPath : appAssetPath('app-icon-dark.png');
|
|
425
427
|
}
|
|
426
428
|
function createAppIconImage(size) {
|
|
427
429
|
const image = electron_1.nativeImage.createFromPath(themedAppIconPath());
|
|
@@ -1880,6 +1882,17 @@ else {
|
|
|
1880
1882
|
ensureWorkspaceRegistryWatcher();
|
|
1881
1883
|
restoreStoredFlowSuspension();
|
|
1882
1884
|
recordStartup('agent-ready');
|
|
1885
|
+
// 远程触及开关开启 → GUI 进程内托管启动 mobile server(托盘常驻不中断)
|
|
1886
|
+
if (agent.config.getBool('remote', 'touch_enabled')) {
|
|
1887
|
+
try {
|
|
1888
|
+
const { runServer } = require('./server');
|
|
1889
|
+
runServer(root);
|
|
1890
|
+
recordStartup('mobile-server-hosted');
|
|
1891
|
+
}
|
|
1892
|
+
catch (error) {
|
|
1893
|
+
console.error('[Newmark] hosted mobile server failed:', error instanceof Error ? error.message : String(error));
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1883
1896
|
}
|
|
1884
1897
|
};
|
|
1885
1898
|
const localConversationSnapshotForStartup = (target) => {
|
|
@@ -3472,6 +3485,7 @@ else {
|
|
|
3472
3485
|
},
|
|
3473
3486
|
configuredAgentBackend: agent.config.getBool('agent', 'run_in_wsl') ? 'wsl' : 'windows',
|
|
3474
3487
|
agentBackendRestartRequired: (agent.config.getBool('agent', 'run_in_wsl') ? 'wsl' : 'windows') !== activeAgentBackendMode,
|
|
3488
|
+
remoteTouchEnabled: agent.config.getBool('remote', 'touch_enabled'),
|
|
3475
3489
|
wslAvailable: wslDistros.length > 0,
|
|
3476
3490
|
wslDistros,
|
|
3477
3491
|
};
|
|
@@ -4784,6 +4798,15 @@ else {
|
|
|
4784
4798
|
return { servers: mcpManager.list(), discovered };
|
|
4785
4799
|
});
|
|
4786
4800
|
electron_1.ipcMain.handle('dsh:discover', async () => (0, dshCompatibility_1.discoverDshCompatibility)(root));
|
|
4801
|
+
electron_1.ipcMain.handle('dsh:installBundle', async (_event, manifestPath) => {
|
|
4802
|
+
return (0, dshCompatibility_1.installDshBundle)(root, String(manifestPath || ''));
|
|
4803
|
+
});
|
|
4804
|
+
electron_1.ipcMain.handle('dsh:uninstallBundle', async (_event, name) => {
|
|
4805
|
+
return (0, dshCompatibility_1.uninstallDshBundle)(root, String(name || ''));
|
|
4806
|
+
});
|
|
4807
|
+
electron_1.ipcMain.handle('dsh:setBundleEnabled', async (_event, name, enabled) => {
|
|
4808
|
+
return (0, dshCompatibility_1.setDshBundleEnabled)(root, String(name || ''), enabled === true);
|
|
4809
|
+
});
|
|
4787
4810
|
electron_1.ipcMain.handle('mcp:upsert', async (_event, input) => {
|
|
4788
4811
|
if (!mcpManager)
|
|
4789
4812
|
return { ok: false, error: 'MCP manager is unavailable.' };
|
|
@@ -4855,6 +4878,21 @@ else {
|
|
|
4855
4878
|
electron_1.ipcMain.handle('update:version', async () => {
|
|
4856
4879
|
return { ok: true, version: (0, installUpdate_1.currentAppVersion)(), root };
|
|
4857
4880
|
});
|
|
4881
|
+
electron_1.ipcMain.handle('mobile:pairingQr', async () => {
|
|
4882
|
+
const qr = await (0, mobilePairing_1.pairingQrDataUrl)(root);
|
|
4883
|
+
return {
|
|
4884
|
+
ok: true,
|
|
4885
|
+
url: qr.session.url,
|
|
4886
|
+
dataUrl: qr.dataUrl,
|
|
4887
|
+
pairingId: qr.session.pairingId,
|
|
4888
|
+
expiresAt: qr.session.expiresAt,
|
|
4889
|
+
tokenFile: (0, mobilePairing_1.pairingTokenPath)(root),
|
|
4890
|
+
tailscaleIpv4: (0, mobilePairing_1.tailscaleIpv4)(),
|
|
4891
|
+
};
|
|
4892
|
+
});
|
|
4893
|
+
electron_1.ipcMain.handle('mobile:pairingStatus', async () => {
|
|
4894
|
+
return { ok: true, status: (0, mobilePairing_1.pairingStatus)(root) };
|
|
4895
|
+
});
|
|
4858
4896
|
electron_1.ipcMain.handle('update:checkGithub', async (_event, input = {}) => {
|
|
4859
4897
|
return (0, installUpdate_1.checkGitHubUpdate)(String(input.repo || ''), String(input.tag || ''), String(input.asset || ''));
|
|
4860
4898
|
});
|
|
@@ -4884,6 +4922,29 @@ else {
|
|
|
4884
4922
|
setTimeout(() => electron_1.app.quit(), 150);
|
|
4885
4923
|
return result;
|
|
4886
4924
|
});
|
|
4925
|
+
electron_1.ipcMain.handle('update:planMsi', async (_event, input = {}) => {
|
|
4926
|
+
return (0, installUpdate_1.planManagedMsiInstall)(String(input.msiPath || ''), {
|
|
4927
|
+
stopConfirmed: input.stopConfirmed === true,
|
|
4928
|
+
removeLegacyConfirmed: input.removeLegacyConfirmed === true,
|
|
4929
|
+
uninstallPrevious: input.uninstallPrevious !== false,
|
|
4930
|
+
allowElevate: input.allowElevate !== false,
|
|
4931
|
+
excludeRoots: Array.isArray(input.excludeRoots) ? input.excludeRoots.map(String) : undefined,
|
|
4932
|
+
logDir: typeof input.logDir === 'string' ? input.logDir : undefined,
|
|
4933
|
+
});
|
|
4934
|
+
});
|
|
4935
|
+
electron_1.ipcMain.handle('update:executeMsi', async (_event, input = {}) => {
|
|
4936
|
+
const result = (0, installUpdate_1.executeManagedMsiInstall)(String(input.msiPath || ''), {
|
|
4937
|
+
stopConfirmed: input.stopConfirmed === true,
|
|
4938
|
+
removeLegacyConfirmed: input.removeLegacyConfirmed === true,
|
|
4939
|
+
uninstallPrevious: input.uninstallPrevious !== false,
|
|
4940
|
+
allowElevate: input.allowElevate !== false,
|
|
4941
|
+
excludeRoots: Array.isArray(input.excludeRoots) ? input.excludeRoots.map(String) : undefined,
|
|
4942
|
+
logDir: typeof input.logDir === 'string' ? input.logDir : undefined,
|
|
4943
|
+
});
|
|
4944
|
+
if (result.ok)
|
|
4945
|
+
setTimeout(() => electron_1.app.quit(), 150);
|
|
4946
|
+
return result;
|
|
4947
|
+
});
|
|
4887
4948
|
electron_1.ipcMain.handle('github:gh', async (_event, argv = []) => {
|
|
4888
4949
|
const safeArgs = Array.isArray(argv) ? argv.map(String).filter(a => a.length < 400) : [];
|
|
4889
4950
|
try {
|
package/dist/preload.js
CHANGED
|
@@ -124,6 +124,9 @@ contextBridge.exposeInMainWorld('api', {
|
|
|
124
124
|
refreshSkills: () => ipcRenderer.invoke('skills:refresh'),
|
|
125
125
|
listMcpServers: () => ipcRenderer.invoke('mcp:list'),
|
|
126
126
|
discoverDshCompatibility: () => ipcRenderer.invoke('dsh:discover'),
|
|
127
|
+
installDshBundle: (manifestPath) => ipcRenderer.invoke('dsh:installBundle', manifestPath),
|
|
128
|
+
uninstallDshBundle: (name) => ipcRenderer.invoke('dsh:uninstallBundle', name),
|
|
129
|
+
setDshBundleEnabled: (name, enabled) => ipcRenderer.invoke('dsh:setBundleEnabled', name, enabled),
|
|
127
130
|
upsertMcpServer: (input) => ipcRenderer.invoke('mcp:upsert', input),
|
|
128
131
|
setMcpServerEnabled: (id, enabled) => ipcRenderer.invoke('mcp:setEnabled', id, enabled),
|
|
129
132
|
removeMcpServer: (id) => ipcRenderer.invoke('mcp:remove', id),
|
|
@@ -134,6 +137,8 @@ contextBridge.exposeInMainWorld('api', {
|
|
|
134
137
|
memoryLabUpdate: (input) => ipcRenderer.invoke('memoryLab:update', input),
|
|
135
138
|
memoryLabReindex: () => ipcRenderer.invoke('memoryLab:reindex'),
|
|
136
139
|
updateVersion: () => ipcRenderer.invoke('update:version'),
|
|
140
|
+
mobilePairingQr: () => ipcRenderer.invoke('mobile:pairingQr'),
|
|
141
|
+
mobilePairingStatus: () => ipcRenderer.invoke('mobile:pairingStatus'),
|
|
137
142
|
updateCheckGithub: (input) => ipcRenderer.invoke('update:checkGithub', input),
|
|
138
143
|
updateApplyGithub: (input) => ipcRenderer.invoke('update:applyGithub', input),
|
|
139
144
|
updateInstallLocal: (input) => ipcRenderer.invoke('update:installLocal', input),
|
|
@@ -38,14 +38,18 @@ class ChatCompletionsAdapter {
|
|
|
38
38
|
...(request.systemPrompt ? [{ role: CHAT_SYSTEM_ROLE, content: request.systemPrompt }] : []),
|
|
39
39
|
...(0, chat_messages_1.openAIChatMessages)(request.messages),
|
|
40
40
|
];
|
|
41
|
+
const tools = this.serializeTools(request.tools);
|
|
41
42
|
const body = {
|
|
42
43
|
model: request.model,
|
|
43
44
|
messages,
|
|
44
45
|
temperature: request.temperature,
|
|
45
46
|
max_tokens: request.maxOutputTokens,
|
|
46
|
-
tools: this.serializeTools(request.tools),
|
|
47
|
-
tool_choice: 'auto',
|
|
48
47
|
};
|
|
48
|
+
if (tools.length) {
|
|
49
|
+
body.tools = tools;
|
|
50
|
+
body.tool_choice = 'auto';
|
|
51
|
+
body.parallel_tool_calls = true;
|
|
52
|
+
}
|
|
49
53
|
if (request.reasoningEffort)
|
|
50
54
|
body.reasoning_effort = request.reasoningEffort;
|
|
51
55
|
// 会话标识透传:仅当上层(支持 session_id 语义的 provider)显式填充时写进
|
package/dist/server.d.ts
CHANGED