newmark-agent 0.6.4 → 0.6.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.
Files changed (76) hide show
  1. package/config.example.json +13 -3
  2. package/dist/cli-commands.d.ts +1 -1
  3. package/dist/cli-commands.js +54 -3
  4. package/dist/cli-discovery.js +3 -0
  5. package/dist/conversation-utility-host.bundle.cjs +4472 -1767
  6. package/dist/conversation-utility-host.js +94 -7
  7. package/dist/core/agent.d.ts +126 -12
  8. package/dist/core/agent.js +785 -172
  9. package/dist/core/agentKernelRunner.d.ts +7 -1
  10. package/dist/core/agentKernelRunner.js +160 -20
  11. package/dist/core/autoRouter.d.ts +49 -44
  12. package/dist/core/autoRouter.js +117 -302
  13. package/dist/core/computerUseSession.js +1 -1
  14. package/dist/core/config.js +27 -11
  15. package/dist/core/continuation/contracts.d.ts +1 -1
  16. package/dist/core/continuation/store.d.ts +91 -1
  17. package/dist/core/continuation/store.js +291 -61
  18. package/dist/core/conversationKernel.d.ts +49 -7
  19. package/dist/core/conversationKernel.js +303 -51
  20. package/dist/core/conversationStateDocument.d.ts +18 -0
  21. package/dist/core/conversationStateDocument.js +88 -0
  22. package/dist/core/conversationVisualBudget.d.ts +74 -0
  23. package/dist/core/conversationVisualBudget.js +153 -0
  24. package/dist/core/electronUtilityAgentClient.d.ts +3 -2
  25. package/dist/core/electronUtilityAgentClient.js +32 -8
  26. package/dist/core/electronUtilityRuntimePool.d.ts +28 -3
  27. package/dist/core/electronUtilityRuntimePool.js +93 -24
  28. package/dist/core/fileWriteObservation.d.ts +41 -0
  29. package/dist/core/fileWriteObservation.js +454 -0
  30. package/dist/core/hostRuntimeHooks.d.ts +23 -0
  31. package/dist/core/hostRuntimeHooks.js +17 -0
  32. package/dist/core/jevDecision.d.ts +144 -0
  33. package/dist/core/jevDecision.js +226 -0
  34. package/dist/core/memoryProbe.d.ts +24 -0
  35. package/dist/core/memoryProbe.js +104 -0
  36. package/dist/core/mobilePairing.d.ts +7 -1
  37. package/dist/core/mobilePairing.js +9 -1
  38. package/dist/core/performanceDiagnostics.d.ts +1 -1
  39. package/dist/core/routeDecisionValidator.d.ts +86 -0
  40. package/dist/core/routeDecisionValidator.js +249 -0
  41. package/dist/core/routeEligibility.d.ts +52 -0
  42. package/dist/core/routeEligibility.js +108 -0
  43. package/dist/core/runtimeMemoryBudget.d.ts +6 -0
  44. package/dist/core/runtimeMemoryBudget.js +12 -0
  45. package/dist/core/toolPolicy.d.ts +1 -1
  46. package/dist/core/toolPolicy.js +1 -1
  47. package/dist/core/utilityAgentProtocol.d.ts +8 -10
  48. package/dist/core/utilityHostToolRouter.js +2 -0
  49. package/dist/core/visualDownscale.d.ts +6 -0
  50. package/dist/core/visualDownscale.js +137 -0
  51. package/dist/core/wslAgentClient.d.ts +1 -2
  52. package/dist/core/wslAgentClient.js +0 -8
  53. package/dist/core/wslAgentProtocol.d.ts +1 -10
  54. package/dist/core/wslAgentRuntimePool.d.ts +1 -3
  55. package/dist/core/wslAgentRuntimePool.js +17 -22
  56. package/dist/llm/provider.d.ts +3 -1
  57. package/dist/llm/provider.js +53 -9
  58. package/dist/main.js +107 -30
  59. package/dist/preload.js +3 -1
  60. package/dist/server.js +30 -18
  61. package/dist/tools/computerUse.d.ts +6 -0
  62. package/dist/tools/computerUse.js +406 -21
  63. package/dist/tools/computerUsePowerShellHost.d.ts +6 -1
  64. package/dist/tools/computerUsePowerShellHost.js +105 -31
  65. package/dist/tools/index.d.ts +3 -4
  66. package/dist/tools/index.js +146 -66
  67. package/dist/tui/src/adapters/core-runtime-adapter.js +13 -1
  68. package/dist/tui/src/i18n.js +12 -1
  69. package/dist/tui/src/render.js +9 -2
  70. package/dist/tui/src/settings-schema.js +19 -0
  71. package/dist/tui/src/state.js +69 -1
  72. package/dist/ui/index.html +651 -233
  73. package/dist/ui/lucide-sprite.svg +0 -8
  74. package/dist/wsl-agent-host.bundle.cjs +4302 -1767
  75. package/dist/wsl-agent-host.js +0 -3
  76. package/package.json +39 -10
package/dist/server.js CHANGED
@@ -59,6 +59,17 @@ const workEventCoalescer_1 = require("./core/workEventCoalescer");
59
59
  const conversationListEvent_1 = require("./core/conversationListEvent");
60
60
  const searchMcpPool_1 = require("./core/searchMcpPool");
61
61
  const PORT = 47890;
62
+ /**
63
+ * Effective listen/advertised port. Production and every existing harness use
64
+ * `PORT` untouched (the isolated-server gates patch that literal); the
65
+ * `NEWMARK_MOBILE_PORT` override exists so a second, isolated dev/test instance
66
+ * can host a paired client without taking the production port away from the
67
+ * instance the user is already running. It stays in sync with the pairing
68
+ * URL/QR, which resolves the same override through `MOBILE_PORT`.
69
+ */
70
+ const HOSTED_PORT = Number(process.env.NEWMARK_MOBILE_PORT) > 0
71
+ ? Math.trunc(Number(process.env.NEWMARK_MOBILE_PORT))
72
+ : PORT;
62
73
  let agent = null;
63
74
  let automation = null;
64
75
  let workspaceFileRouter = null;
@@ -104,7 +115,7 @@ function mobileAuthorized(req) {
104
115
  if (bearer.startsWith('Bearer '))
105
116
  return bearer.slice('Bearer '.length).trim() === mobileToken;
106
117
  try {
107
- const url = new URL(req.url || '/', `http://localhost:${PORT}`);
118
+ const url = new URL(req.url || '/', `http://localhost:${HOSTED_PORT}`);
108
119
  const queryToken = url.searchParams.get('token') || '';
109
120
  return queryToken === mobileToken;
110
121
  }
@@ -223,7 +234,7 @@ async function handleMobileWorkspaceUpload(req, res) {
223
234
  req.resume();
224
235
  return;
225
236
  }
226
- const url = new URL(req.url || '/', `http://localhost:${PORT}`);
237
+ const url = new URL(req.url || '/', `http://localhost:${HOSTED_PORT}`);
227
238
  const workspaceId = url.searchParams.get('workspaceId') || '';
228
239
  const directory = url.searchParams.get('directory') || '';
229
240
  const fileName = url.searchParams.get('fileName') || '';
@@ -392,13 +403,17 @@ function mobileScopedAgent(ws, conversationId) {
392
403
  }
393
404
  function mobileConversationRuntimeBusy(current, ws, conversationId) {
394
405
  const scoped = mobileScopedRuntimes.get(mobileRuntimeKey(String(ws.id || ''), conversationId));
395
- if (scoped && scoped.agent.status !== 'idle')
406
+ // Only an in-flight run blocks a mobile mutation. `goal_paused` (a goal the
407
+ // user paused) and `error` (a terminal failure) are not running work, yet
408
+ // treating them as busy refused archiving the conversation the user is
409
+ // actually looking at, which is the common case for a paused goal.
410
+ if (scoped && scoped.agent.status === 'working')
396
411
  return true;
397
412
  const currentWs = current.workspace.current;
398
413
  return !!currentWs
399
414
  && path.resolve(currentWs.path) === path.resolve(ws.path)
400
415
  && current.activeConversationId === conversationId
401
- && current.status !== 'idle';
416
+ && current.status === 'working';
402
417
  }
403
418
  function handleMobileEvents(req, res) {
404
419
  if (agent && !agent.config.getBool('remote', 'touch_enabled')) {
@@ -520,11 +535,7 @@ function applyConfigPatch(cfg) {
520
535
  agent.config.set('models', 'fallback_on_unavailable', value === true || value === 'on');
521
536
  break;
522
537
  case 'switchTendency':
523
- agent.config.set('models', 'auto_switch_preference', value);
524
- break;
525
- case 'clearLearnedAutoPreferences':
526
- if (value === true)
527
- agent.clearLearnedModelPreferences();
538
+ agent.config.set('models', 'auto_switch_preference', ['conservative', 'balanced', 'aggressive'].includes(String(value)) ? String(value) : 'balanced');
528
539
  break;
529
540
  case 'openAIApiMode':
530
541
  agent.config.set('models', 'openai_api_mode', ['chat_stream', 'chat', 'responses'].includes(String(value)) ? value : 'chat_stream');
@@ -594,7 +605,7 @@ function jsonResponse(res, data, code = 200) {
594
605
  res.end(body);
595
606
  }
596
607
  async function handleApi(req, res, body) {
597
- const url = new URL(req.url || '/', `http://localhost:${PORT}`);
608
+ const url = new URL(req.url || '/', `http://localhost:${HOSTED_PORT}`);
598
609
  const pathname = url.pathname;
599
610
  if (pathname.startsWith('/api/mobile/')) {
600
611
  if (agent && !agent.config.getBool('remote', 'touch_enabled')) {
@@ -616,6 +627,7 @@ async function handleApi(req, res, body) {
616
627
  jsonResponse(res, {
617
628
  mode: agent.mode, model: agent.modelSelectionValue(), modelLabel: agent.modelLabel(),
618
629
  resolvedDeployment: agent.activeDeployment(), routeDecision: agent.lastRouteDecision,
630
+ jevDecisionModel: agent.jevDecisionModelState(),
619
631
  intelligence: agent.intelligence, status: agent.status, goal: agent.goal,
620
632
  models: agent.allModelNames(), inputMode: agent.inputMode,
621
633
  conversationId: agent.activeConversationId,
@@ -1769,7 +1781,7 @@ function startServer(root, options = {}) {
1769
1781
  res.end();
1770
1782
  return;
1771
1783
  }
1772
- const url = new URL(req.url || '/', `http://localhost:${PORT}`);
1784
+ const url = new URL(req.url || '/', `http://localhost:${HOSTED_PORT}`);
1773
1785
  if (url.pathname === '/api/mobile/events') {
1774
1786
  handleMobileEvents(req, res);
1775
1787
  return;
@@ -1824,15 +1836,15 @@ function startServer(root, options = {}) {
1824
1836
  if (hostedServer === server)
1825
1837
  hostedServer = null;
1826
1838
  });
1827
- server.listen(PORT, bindHost, () => {
1839
+ server.listen(HOSTED_PORT, bindHost, () => {
1828
1840
  console.log(`\n Newmark Agent v1.0 - Server Mode`);
1829
- console.log(` Bind: ${bindHost}:${PORT}`);
1830
- console.log(` GUI: http://localhost:${PORT}`);
1841
+ console.log(` Bind: ${bindHost}:${HOSTED_PORT}`);
1842
+ console.log(` GUI: http://localhost:${HOSTED_PORT}`);
1831
1843
  console.log(` Tailscale IPv4: ${tailscale || 'not detected'}`);
1832
1844
  console.log(` LAN IPv4: ${lan || 'not detected'}`);
1833
- console.log(` Mobile endpoint: http://${accessHost}:${PORT}/api/mobile/hello?token=<token>`);
1845
+ console.log(` Mobile endpoint: http://${accessHost}:${HOSTED_PORT}/api/mobile/hello?token=<token>`);
1834
1846
  console.log(` Mobile token file: ${tokenPath}`);
1835
- console.log(` Mobile events (SSE): http://${accessHost}:${PORT}/api/mobile/events?token=<token>`);
1847
+ console.log(` Mobile events (SSE): http://${accessHost}:${HOSTED_PORT}/api/mobile/events?token=<token>`);
1836
1848
  console.log(` Press Ctrl+C to stop\n`);
1837
1849
  });
1838
1850
  return server;
@@ -1868,7 +1880,7 @@ async function probeHostedServer(host) {
1868
1880
  return await new Promise(resolve => {
1869
1881
  const request = http.get({
1870
1882
  hostname: host,
1871
- port: PORT,
1883
+ port: HOSTED_PORT,
1872
1884
  path: `/api/mobile/hello?token=${encodeURIComponent(mobileToken)}`,
1873
1885
  timeout: 1800,
1874
1886
  }, response => {
@@ -1935,7 +1947,7 @@ async function hostedServerStatus(enabled = true, probeHost = '') {
1935
1947
  reachable,
1936
1948
  state,
1937
1949
  host,
1938
- port: PORT,
1950
+ port: HOSTED_PORT,
1939
1951
  error: state === 'error' ? (error || 'Mobile server is not reachable') : '',
1940
1952
  checkedAt: new Date().toISOString(),
1941
1953
  startedAt: hostedServerStartedAt,
@@ -30,6 +30,10 @@ export interface ComputerUseOptions {
30
30
  allowEphemeralVisionImage?: boolean;
31
31
  captureMaxWidth?: number;
32
32
  captureMaxHeight?: number;
33
+ sparseWaitMs?: number;
34
+ includeUiTree?: boolean;
35
+ timeoutMs?: number;
36
+ signal?: AbortSignal;
33
37
  gradientColors?: string[];
34
38
  gradientSpeed?: number;
35
39
  gradientWidth?: number;
@@ -50,10 +54,12 @@ declare function ephemeralScreenshotPath(kind: 'observe' | 'app', directory?: st
50
54
  declare function cleanupStaleScreenshots(options?: ScreenshotCleanupOptions): {
51
55
  removed: number;
52
56
  };
57
+ declare function sparseMeasurementSampleBudget(waitMs: number): number;
53
58
  declare function stringifyComputerUseResult(result: Record<string, unknown>): string;
54
59
  export declare const computerUseInternals: {
55
60
  cleanupStaleScreenshots: typeof cleanupStaleScreenshots;
56
61
  ephemeralScreenshotPath: typeof ephemeralScreenshotPath;
62
+ sparseMeasurementSampleBudget: typeof sparseMeasurementSampleBudget;
57
63
  stringifyComputerUseResult: typeof stringifyComputerUseResult;
58
64
  };
59
65
  export declare function runComputerUse(options: ComputerUseOptions): Promise<string>;