newmark-agent 0.5.1 → 0.5.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.
@@ -327672,7 +327672,9 @@ var ConfigManager = class {
327672
327672
  this.backupConfig(cp, "invalid-shape");
327673
327673
  return this.writeRecoveredConfig(cp);
327674
327674
  }
327675
- if (migrateProviderIdsInConfig(normalized)) {
327675
+ const providerIdsMigrated = migrateProviderIdsInConfig(normalized);
327676
+ const marqueeConfigRemoved = removeDeprecatedMarqueeConfig(normalized);
327677
+ if (providerIdsMigrated || marqueeConfigRemoved) {
327676
327678
  try {
327677
327679
  if (!this.readOnly) fs3.writeFileSync(cp, JSON.stringify(normalized, null, 2), "utf-8");
327678
327680
  } catch {
@@ -327991,6 +327993,18 @@ function normalizeConfigShape(raw, withDefaults) {
327991
327993
  }
327992
327994
  return base2;
327993
327995
  }
327996
+ function removeDeprecatedMarqueeConfig(config) {
327997
+ const ui = config.ui;
327998
+ if (!ui) return false;
327999
+ let changed = false;
328000
+ for (const key3 of ["gradient_colors", "gradient_speed", "gradient_width"]) {
328001
+ if (Object.prototype.hasOwnProperty.call(ui, key3)) {
328002
+ delete ui[key3];
328003
+ changed = true;
328004
+ }
328005
+ }
328006
+ return changed;
328007
+ }
327994
328008
  function isConfigEntry(value) {
327995
328009
  return !!value && typeof value === "object" && !Array.isArray(value) && Object.prototype.hasOwnProperty.call(value, "value");
327996
328010
  }
@@ -328358,9 +328372,6 @@ function defaultConfig() {
328358
328372
  auto_download: { _description: "Auto-download skills", _type: "choice", _values: ["aggressive", "conservative", "disabled"], value: "conservative" }
328359
328373
  },
328360
328374
  ui: {
328361
- gradient_colors: { _description: "Gradient colors (hex)", _type: "array", value: ["#00ff88", "#00ccff", "#aa44ff", "#ff4488"] },
328362
- gradient_speed: { _description: "Animation speed 1-5", _type: "range", _min: 1, _max: 5, value: 2 },
328363
- gradient_width: { _description: "Border width", _type: "integer", _min: 1, _max: 4, value: 2 },
328364
328375
  glass_alpha: { _description: "Glass opacity", _type: "range", _min: 0, _max: 1, value: 0.85 },
328365
328376
  show_mode_label: { _description: "Show mode on hover", _type: "boolean", value: true },
328366
328377
  left_panel_collapsed: { _description: "Left panel collapsed", _type: "boolean", value: false },
@@ -329201,7 +329212,10 @@ var ResponsesAdapter = class {
329201
329212
  if (eventType === "response.reasoning_summary_text.delta") {
329202
329213
  const key3 = `${String(payload.item_id || "")}:${String(payload.summary_index || 0)}`;
329203
329214
  const delta = this.extractText(payload.delta);
329204
- if (delta) reasoningSummaries.set(key3, (reasoningSummaries.get(key3) || "") + delta);
329215
+ if (delta) {
329216
+ reasoningSummaries.set(key3, (reasoningSummaries.get(key3) || "") + delta);
329217
+ yield { type: "reasoning.summary.delta", delta };
329218
+ }
329205
329219
  continue;
329206
329220
  }
329207
329221
  if (eventType === "response.reasoning_summary_text.done") {
@@ -329393,7 +329407,7 @@ function createProviderAdapter(providerId, apiMode) {
329393
329407
  }
329394
329408
 
329395
329409
  // src/llm/provider.ts
329396
- var DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS = 9e4;
329410
+ var DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS = 0;
329397
329411
  var MIN_PROVIDER_REQUEST_TIMEOUT_MS = 50;
329398
329412
  function providerTimeoutError(timeoutMs) {
329399
329413
  const error = new Error(`Provider request timed out after ${timeoutMs}ms`);
@@ -329454,11 +329468,13 @@ var LLMProvider = class _LLMProvider {
329454
329468
  static powershellTransport = null;
329455
329469
  temperatureUnsupported = /* @__PURE__ */ new Set();
329456
329470
  effectiveRequestTimeout(timeoutMs) {
329457
- const requested = Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS;
329458
- const configured = Number.isFinite(this.requestTimeoutMs) && this.requestTimeoutMs > 0 ? this.requestTimeoutMs : DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS;
329471
+ const requested = Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : 0;
329472
+ const configured = Number.isFinite(this.requestTimeoutMs) && this.requestTimeoutMs > 0 ? this.requestTimeoutMs : 0;
329473
+ if (requested <= 0 || configured <= 0) return 0;
329459
329474
  return Math.max(MIN_PROVIDER_REQUEST_TIMEOUT_MS, Math.min(requested, configured));
329460
329475
  }
329461
329476
  async withRequestTimeout(promise, timeoutMs, signal) {
329477
+ if (timeoutMs <= 0) return await abortable(promise, signal);
329462
329478
  let timer;
329463
329479
  const timeoutPromise = new Promise((_3, reject) => {
329464
329480
  timer = setTimeout(() => reject(providerTimeoutError(timeoutMs)), timeoutMs);
@@ -329658,7 +329674,7 @@ var LLMProvider = class _LLMProvider {
329658
329674
  const forwardAbort = () => abort.abort(signal?.reason);
329659
329675
  if (signal?.aborted) forwardAbort();
329660
329676
  else signal?.addEventListener("abort", forwardAbort, { once: true });
329661
- const timer = setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout);
329677
+ const timer = effectiveTimeout > 0 ? setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout) : void 0;
329662
329678
  try {
329663
329679
  const response = await fetch(url, {
329664
329680
  method: "POST",
@@ -329687,7 +329703,7 @@ var LLMProvider = class _LLMProvider {
329687
329703
  async getJsonWithFetchFallback(url, headers, timeoutMs = 3e4) {
329688
329704
  const effectiveTimeout = this.effectiveRequestTimeout(timeoutMs);
329689
329705
  const abort = new AbortController();
329690
- const timer = setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout);
329706
+ const timer = effectiveTimeout > 0 ? setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout) : void 0;
329691
329707
  try {
329692
329708
  const response = await fetch(url, { method: "GET", headers, signal: abort.signal });
329693
329709
  return response;
@@ -329761,9 +329777,11 @@ var LLMProvider = class _LLMProvider {
329761
329777
  else fail(new Error("Node HTTP response closed before completion"));
329762
329778
  });
329763
329779
  });
329764
- req.setTimeout(effectiveTimeout, () => {
329765
- req.destroy(providerTimeoutError(effectiveTimeout));
329766
- });
329780
+ if (effectiveTimeout > 0) {
329781
+ req.setTimeout(effectiveTimeout, () => {
329782
+ req.destroy(providerTimeoutError(effectiveTimeout));
329783
+ });
329784
+ }
329767
329785
  req.on("error", reject);
329768
329786
  const onAbort = () => req.destroy(abortFailure(signal));
329769
329787
  if (signal?.aborted) onAbort();
@@ -329812,7 +329830,7 @@ var LLMProvider = class _LLMProvider {
329812
329830
  " $raw = $headerJson | ConvertFrom-Json",
329813
329831
  " foreach ($p in $raw.PSObject.Properties) { $headers[$p.Name] = [string]$p.Value }",
329814
329832
  "}",
329815
- `'$params = @{ Uri = $uri; Method = $method; Headers = $headers; UseBasicParsing = $true; TimeoutSec = ${Math.max(1, Math.ceil(effectiveTimeout / 1e3))} }`,
329833
+ effectiveTimeout > 0 ? `$params = @{ Uri = $uri; Method = $method; Headers = $headers; UseBasicParsing = $true; TimeoutSec = ${Math.ceil(effectiveTimeout / 1e3)} }` : "$params = @{ Uri = $uri; Method = $method; Headers = $headers; UseBasicParsing = $true }",
329816
329834
  'if ($method -eq "POST") { $params["Body"] = $bodyJson }',
329817
329835
  'if ($method -eq "POST") { $params["ContentType"] = "application/json; charset=utf-8" }',
329818
329836
  "$resp = Invoke-WebRequest @params",
@@ -329841,11 +329859,11 @@ var LLMProvider = class _LLMProvider {
329841
329859
  };
329842
329860
  if (signal?.aborted) onAbort();
329843
329861
  else signal?.addEventListener("abort", onAbort, { once: true });
329844
- const timer = setTimeout(() => {
329862
+ const timer = effectiveTimeout > 0 ? setTimeout(() => {
329845
329863
  child.kill();
329846
329864
  cleanup();
329847
329865
  reject(providerTimeoutError(effectiveTimeout));
329848
- }, effectiveTimeout + 5e3);
329866
+ }, effectiveTimeout + 5e3) : void 0;
329849
329867
  child.stdout.setEncoding("utf8");
329850
329868
  child.stderr.setEncoding("utf8");
329851
329869
  child.stdout.on("data", (chunk) => {
@@ -330195,16 +330213,12 @@ ${responsePath}
330195
330213
  const transport = this.buildProviderAdapterTransport();
330196
330214
  const streaming = mode === "chat_stream";
330197
330215
  const reasoningState = { current: "" };
330198
- let reasoningStatusEmitted = false;
330199
330216
  for await (const event of adapter.execute(serialized, execSignal, transport)) {
330200
330217
  if (event.type === "response.started" || event.type === "response.completed") continue;
330201
330218
  if (event.type === "tool_call.started" || event.type === "tool_call.arguments.delta") continue;
330202
330219
  if (event.type === "reasoning.summary.delta") {
330203
330220
  reasoningState.current += event.delta;
330204
- if (!streaming && !reasoningStatusEmitted) {
330205
- reasoningStatusEmitted = true;
330206
- yield { type: "status", text: "", reasoningContent: reasoningState.current };
330207
- }
330221
+ yield { type: "status", text: "", reasoningContent: reasoningState.current };
330208
330222
  continue;
330209
330223
  }
330210
330224
  if (event.type === "text.delta") {
@@ -330256,11 +330270,20 @@ ${responsePath}
330256
330270
  serialized.headers["Accept"] = "text/event-stream";
330257
330271
  const execSignal = signal ?? new AbortController().signal;
330258
330272
  const transport = this.buildProviderAdapterTransport();
330273
+ let reasoningSummary = "";
330259
330274
  for await (const event of adapter.execute(serialized, execSignal, transport)) {
330260
330275
  if (event.type === "response.started" || event.type === "response.completed") continue;
330261
330276
  if (event.type === "tool_call.started" || event.type === "tool_call.arguments.delta") continue;
330277
+ if (event.type === "reasoning.summary.delta") {
330278
+ reasoningSummary += event.delta;
330279
+ yield { type: "status", text: "", reasoningContent: reasoningSummary };
330280
+ continue;
330281
+ }
330262
330282
  if (event.type === "reasoning.summary.done") {
330263
- if (event.summary) yield { type: "status", text: event.summary };
330283
+ if (event.summary && event.summary !== reasoningSummary) {
330284
+ reasoningSummary = event.summary;
330285
+ yield { type: "status", text: "", reasoningContent: reasoningSummary };
330286
+ }
330264
330287
  continue;
330265
330288
  }
330266
330289
  if (event.type === "text.delta") {
@@ -330309,7 +330332,7 @@ ${responsePath}
330309
330332
  if (signal?.aborted) forwardAbort();
330310
330333
  else signal?.addEventListener("abort", forwardAbort, { once: true });
330311
330334
  const effectiveTimeout = this.effectiveRequestTimeout(12e4);
330312
- const timer = setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout);
330335
+ const timer = effectiveTimeout > 0 ? setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout) : void 0;
330313
330336
  try {
330314
330337
  try {
330315
330338
  let response2 = await fetch(request.url, {
@@ -330454,7 +330477,7 @@ ${responsePath}
330454
330477
  if (signal?.aborted) forwardAbort();
330455
330478
  else signal?.addEventListener("abort", forwardAbort, { once: true });
330456
330479
  const effectiveTimeout = this.effectiveRequestTimeout(12e4);
330457
- const timeout = setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout);
330480
+ const timeout = effectiveTimeout > 0 ? setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout) : void 0;
330458
330481
  let reader = null;
330459
330482
  try {
330460
330483
  let response;
@@ -330509,6 +330532,7 @@ ${responsePath}
330509
330532
  if (!delta) continue;
330510
330533
  if (delta.reasoning_content) {
330511
330534
  currentReasoningContent += delta.reasoning_content;
330535
+ yield { type: "status", text: "", reasoningContent: currentReasoningContent };
330512
330536
  }
330513
330537
  const deltaText = this.extractTextValue(delta.content);
330514
330538
  if (deltaText) {
@@ -333758,11 +333782,8 @@ function jpegCaptureScript(outPath, boundsScript, requestedMaxWidth, requestedMa
333758
333782
  'Write-Output (@{ ok=$true; left=$x; top=$y; width=$w; height=$h; capture_max_width=$maxWidth; capture_max_height=$maxHeight; image_width=$imageWidth; image_height=$imageHeight; image_bytes=$fileSize; image_quality=$qualityUsed; image_available=$imageAvailable; image_mime="image/jpeg" } | ConvertTo-Json -Compress)'
333759
333783
  ].join("\r\n");
333760
333784
  }
333761
- function gradientPalette(input) {
333762
- const fallback = ["#00ff88", "#00ccff", "#aa44ff", "#ff4488"];
333763
- const configured = Array.isArray(input) ? input : [];
333764
- const raw = configured.length ? configured.map((v) => String(v || "").trim()).filter(Boolean) : String(process.env.NEWMARK_COMPUTER_USE_GRADIENT || "").split(",").map((v) => v.trim()).filter(Boolean);
333765
- return raw.length >= 2 ? raw.slice(0, 6) : fallback;
333785
+ function gradientPalette(_input) {
333786
+ return ["#000000", "#ffffff", "#000000", "#ffffff"];
333766
333787
  }
333767
333788
  async function stopTakeoverOverlay() {
333768
333789
  const pid = takeoverOverlayPid;
@@ -333784,11 +333805,11 @@ async function stopTakeoverOverlay() {
333784
333805
  async function startTakeoverOverlay(durationMs = 0, input = {}) {
333785
333806
  if (process.platform !== "win32") return { ok: false, action: "takeover_start", error: "Computer Use takeover overlay is Windows-only." };
333786
333807
  await stopTakeoverOverlay();
333787
- lastTakeoverOverlayStyle = { colors: input.colors, speed: input.speed, width: input.width };
333808
+ lastTakeoverOverlayStyle = { colors: gradientPalette(), speed: 3, width: 2 };
333788
333809
  const colors = gradientPalette(input.colors);
333789
333810
  const lifetime = Math.max(0, Math.floor(Number(durationMs || 0)));
333790
- const width = Math.max(1, Math.min(24, Math.floor(Number(input.width || 2))));
333791
- const speedSeconds = Math.max(0.25, Math.min(30, Number(input.speed || 2)));
333811
+ const width = 2;
333812
+ const speedSeconds = 3;
333792
333813
  const ownerPid = Math.max(0, Math.floor(Number(input.ownerPid ?? process.pid) || 0));
333793
333814
  const scriptPath = path9.join(tempScreenshotDir(), `takeover-overlay-${timestampName()}-${crypto6.randomBytes(4).toString("hex")}.ps1`);
333794
333815
  const script = [
@@ -337559,9 +337580,9 @@ var ToolExecutor = class {
337559
337580
  allowEphemeralVisionImage: context.allowEphemeralVisionImage === true,
337560
337581
  captureMaxWidth: Number(args.capture_max_width),
337561
337582
  captureMaxHeight: Number(args.capture_max_height),
337562
- gradientColors: Array.isArray(args.gradient_colors) ? args.gradient_colors : this.config.get("ui", "gradient_colors") || [],
337563
- gradientSpeed: args.gradient_speed !== void 0 ? Number(args.gradient_speed) : this.config.getNum("ui", "gradient_speed"),
337564
- gradientWidth: args.gradient_width !== void 0 ? Number(args.gradient_width) : this.config.getNum("ui", "gradient_width"),
337583
+ gradientColors: Array.isArray(args.gradient_colors) ? args.gradient_colors : void 0,
337584
+ gradientSpeed: args.gradient_speed !== void 0 ? Number(args.gradient_speed) : void 0,
337585
+ gradientWidth: args.gradient_width !== void 0 ? Number(args.gradient_width) : void 0,
337565
337586
  invocation: context.invocation,
337566
337587
  ownerId: owner,
337567
337588
  includeRawUi: args.include_raw_ui === true,
@@ -340962,6 +340983,7 @@ async function runAgentKernel(agent) {
340962
340983
  currentAgent.emitWorkEvent({ type: "thought", content: "" });
340963
340984
  }
340964
340985
  if (delta) {
340986
+ currentAgent.emitWorkEvent({ type: "thought_delta", content: delta });
340965
340987
  stream2.push({ type: "thinking_delta", contentIndex, delta, partial: assistantMessage2(model, thinking ? [{ type: "text", text }] : [], "stop") });
340966
340988
  }
340967
340989
  }
@@ -346693,7 +346715,7 @@ ${String(event.toolArgs || "")}`;
346693
346715
  id: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
346694
346716
  conversationId: input.conversationId || this.activeConversationId || "default",
346695
346717
  type: publishedType,
346696
- content: isToolEvent ? this.publicToolEventContent(publishedType, toolName) : input.type === "text" ? this.sanitizeAssistantStreamingOutput(input.content || "") : this.sanitizePublicWorkContent(input.content || ""),
346718
+ content: isToolEvent ? this.publicToolEventContent(publishedType, toolName) : input.type === "text" || input.type === "thought_delta" ? this.sanitizeAssistantStreamingOutput(input.content || "") : this.sanitizePublicWorkContent(input.content || ""),
346697
346719
  mode: input.mode || this.modeName(),
346698
346720
  model: input.model || this.model,
346699
346721
  timestamp: input.timestamp || this.nowLabel(),
@@ -2280,7 +2280,7 @@ class Agent {
2280
2280
  type: publishedType,
2281
2281
  content: isToolEvent
2282
2282
  ? this.publicToolEventContent(publishedType, toolName)
2283
- : input.type === 'text'
2283
+ : input.type === 'text' || input.type === 'thought_delta'
2284
2284
  ? this.sanitizeAssistantStreamingOutput(input.content || '')
2285
2285
  : this.sanitizePublicWorkContent(input.content || ''),
2286
2286
  mode: input.mode || this.modeName(),
@@ -576,6 +576,7 @@ async function runAgentKernel(agent) {
576
576
  currentAgent.emitWorkEvent({ type: 'thought', content: '' });
577
577
  }
578
578
  if (delta) {
579
+ currentAgent.emitWorkEvent({ type: 'thought_delta', content: delta });
579
580
  stream.push({ type: 'thinking_delta', contentIndex, delta, partial: assistantMessage(model, thinking ? [{ type: 'text', text }] : [], 'stop') });
580
581
  }
581
582
  }
@@ -87,7 +87,9 @@ class ConfigManager {
87
87
  this.backupConfig(cp, 'invalid-shape');
88
88
  return this.writeRecoveredConfig(cp);
89
89
  }
90
- if (migrateProviderIdsInConfig(normalized)) {
90
+ const providerIdsMigrated = migrateProviderIdsInConfig(normalized);
91
+ const marqueeConfigRemoved = removeDeprecatedMarqueeConfig(normalized);
92
+ if (providerIdsMigrated || marqueeConfigRemoved) {
91
93
  // Provider ids are routing identities, so legacy/malformed catalogs must
92
94
  // not wait for an unrelated settings save before becoming collision-safe.
93
95
  try {
@@ -457,6 +459,19 @@ function normalizeConfigShape(raw, withDefaults) {
457
459
  }
458
460
  return base;
459
461
  }
462
+ function removeDeprecatedMarqueeConfig(config) {
463
+ const ui = config.ui;
464
+ if (!ui)
465
+ return false;
466
+ let changed = false;
467
+ for (const key of ['gradient_colors', 'gradient_speed', 'gradient_width']) {
468
+ if (Object.prototype.hasOwnProperty.call(ui, key)) {
469
+ delete ui[key];
470
+ changed = true;
471
+ }
472
+ }
473
+ return changed;
474
+ }
460
475
  function isConfigEntry(value) {
461
476
  return !!value && typeof value === 'object' && !Array.isArray(value) && Object.prototype.hasOwnProperty.call(value, 'value');
462
477
  }
@@ -892,9 +907,6 @@ function defaultConfig() {
892
907
  auto_download: { _description: "Auto-download skills", _type: "choice", _values: ["aggressive", "conservative", "disabled"], value: "conservative" },
893
908
  },
894
909
  ui: {
895
- gradient_colors: { _description: "Gradient colors (hex)", _type: "array", value: ["#00ff88", "#00ccff", "#aa44ff", "#ff4488"] },
896
- gradient_speed: { _description: "Animation speed 1-5", _type: "range", _min: 1, _max: 5, value: 2 },
897
- gradient_width: { _description: "Border width", _type: "integer", _min: 1, _max: 4, value: 2 },
898
910
  glass_alpha: { _description: "Glass opacity", _type: "range", _min: 0, _max: 1, value: 0.85 },
899
911
  show_mode_label: { _description: "Show mode on hover", _type: "boolean", value: true },
900
912
  left_panel_collapsed: { _description: "Left panel collapsed", _type: "boolean", value: false },
@@ -100,7 +100,7 @@ export interface ChatMessage {
100
100
  export interface AgentWorkEvent {
101
101
  id: string;
102
102
  conversationId: string;
103
- type: 'start' | 'text' | 'response' | 'final_response' | 'tool_call' | 'tool_result' | 'thought' | 'thought_result' | 'status' | 'done' | 'error' | 'queue_update' | 'guide';
103
+ type: 'start' | 'text' | 'response' | 'final_response' | 'tool_call' | 'tool_result' | 'thought' | 'thought_delta' | 'thought_result' | 'status' | 'done' | 'error' | 'queue_update' | 'guide';
104
104
  content: string;
105
105
  mode: string;
106
106
  model: string;
@@ -1,7 +1,7 @@
1
1
  import type { AgentWorkEvent } from './types';
2
2
  /**
3
- * Bounds cross-process traffic for high-rate streaming text without changing
4
- * durable work-run events. Non-text events always flush pending text first.
3
+ * Bounds cross-process traffic for high-rate response and thought deltas
4
+ * without changing durable work-run events. Lifecycle events flush deltas first.
5
5
  */
6
6
  export declare class WorkEventCoalescer {
7
7
  private readonly emit;
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.WorkEventCoalescer = void 0;
4
4
  /**
5
- * Bounds cross-process traffic for high-rate streaming text without changing
6
- * durable work-run events. Non-text events always flush pending text first.
5
+ * Bounds cross-process traffic for high-rate response and thought deltas
6
+ * without changing durable work-run events. Lifecycle events flush deltas first.
7
7
  */
8
8
  class WorkEventCoalescer {
9
9
  emit;
@@ -14,12 +14,12 @@ class WorkEventCoalescer {
14
14
  this.windowMs = windowMs;
15
15
  }
16
16
  push(event) {
17
- if (event.type !== 'text') {
17
+ if (event.type !== 'text' && event.type !== 'thought_delta') {
18
18
  this.flushAll();
19
19
  this.emit(event);
20
20
  return;
21
21
  }
22
- const key = `${event.workspaceId || ''}::${event.conversationId}::${event.runtimeKey || ''}::${event.runId || ''}`;
22
+ const key = `${event.type}::${event.workspaceId || ''}::${event.conversationId}::${event.runtimeKey || ''}::${event.runId || ''}`;
23
23
  const current = this.pending.get(key);
24
24
  if (current) {
25
25
  current.content += event.content;
@@ -46,7 +46,9 @@ const providers_1 = require("../providers");
46
46
  // Keep provider requests below the release-harness/user-visible command
47
47
  // deadline. A provider that does not answer must produce one bounded error;
48
48
  // it must not restart the same request through every Windows transport.
49
- const DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS = 90_000;
49
+ // Provider responses are intentionally unbounded. User cancellation, transport
50
+ // errors, and tool-specific limits remain the only automatic stop conditions.
51
+ const DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS = 0;
50
52
  const MIN_PROVIDER_REQUEST_TIMEOUT_MS = 50;
51
53
  function providerTimeoutError(timeoutMs) {
52
54
  const error = new Error(`Provider request timed out after ${timeoutMs}ms`);
@@ -115,13 +117,17 @@ class LLMProvider {
115
117
  this.thinkingTierMaps = thinkingTierMaps;
116
118
  }
117
119
  effectiveRequestTimeout(timeoutMs) {
118
- const requested = Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS;
120
+ const requested = Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : 0;
119
121
  const configured = Number.isFinite(this.requestTimeoutMs) && this.requestTimeoutMs > 0
120
122
  ? this.requestTimeoutMs
121
- : DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS;
123
+ : 0;
124
+ if (requested <= 0 || configured <= 0)
125
+ return 0;
122
126
  return Math.max(MIN_PROVIDER_REQUEST_TIMEOUT_MS, Math.min(requested, configured));
123
127
  }
124
128
  async withRequestTimeout(promise, timeoutMs, signal) {
129
+ if (timeoutMs <= 0)
130
+ return await abortable(promise, signal);
125
131
  let timer;
126
132
  const timeoutPromise = new Promise((_, reject) => {
127
133
  timer = setTimeout(() => reject(providerTimeoutError(timeoutMs)), timeoutMs);
@@ -362,7 +368,9 @@ class LLMProvider {
362
368
  forwardAbort();
363
369
  else
364
370
  signal?.addEventListener('abort', forwardAbort, { once: true });
365
- const timer = setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout);
371
+ const timer = effectiveTimeout > 0
372
+ ? setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout)
373
+ : undefined;
366
374
  try {
367
375
  const response = await fetch(url, {
368
376
  method: 'POST',
@@ -396,7 +404,9 @@ class LLMProvider {
396
404
  async getJsonWithFetchFallback(url, headers, timeoutMs = 30000) {
397
405
  const effectiveTimeout = this.effectiveRequestTimeout(timeoutMs);
398
406
  const abort = new AbortController();
399
- const timer = setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout);
407
+ const timer = effectiveTimeout > 0
408
+ ? setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout)
409
+ : undefined;
400
410
  try {
401
411
  const response = await fetch(url, { method: 'GET', headers, signal: abort.signal });
402
412
  return response;
@@ -482,9 +492,11 @@ class LLMProvider {
482
492
  fail(new Error('Node HTTP response closed before completion'));
483
493
  });
484
494
  });
485
- req.setTimeout(effectiveTimeout, () => {
486
- req.destroy(providerTimeoutError(effectiveTimeout));
487
- });
495
+ if (effectiveTimeout > 0) {
496
+ req.setTimeout(effectiveTimeout, () => {
497
+ req.destroy(providerTimeoutError(effectiveTimeout));
498
+ });
499
+ }
488
500
  req.on('error', reject);
489
501
  const onAbort = () => req.destroy(abortFailure(signal));
490
502
  if (signal?.aborted)
@@ -538,7 +550,9 @@ class LLMProvider {
538
550
  ' $raw = $headerJson | ConvertFrom-Json',
539
551
  ' foreach ($p in $raw.PSObject.Properties) { $headers[$p.Name] = [string]$p.Value }',
540
552
  '}',
541
- `'$params = @{ Uri = $uri; Method = $method; Headers = $headers; UseBasicParsing = $true; TimeoutSec = ${Math.max(1, Math.ceil(effectiveTimeout / 1000))} }`,
553
+ effectiveTimeout > 0
554
+ ? `$params = @{ Uri = $uri; Method = $method; Headers = $headers; UseBasicParsing = $true; TimeoutSec = ${Math.ceil(effectiveTimeout / 1000)} }`
555
+ : '$params = @{ Uri = $uri; Method = $method; Headers = $headers; UseBasicParsing = $true }',
542
556
  'if ($method -eq "POST") { $params["Body"] = $bodyJson }',
543
557
  'if ($method -eq "POST") { $params["ContentType"] = "application/json; charset=utf-8" }',
544
558
  '$resp = Invoke-WebRequest @params',
@@ -569,11 +583,11 @@ class LLMProvider {
569
583
  onAbort();
570
584
  else
571
585
  signal?.addEventListener('abort', onAbort, { once: true });
572
- const timer = setTimeout(() => {
586
+ const timer = effectiveTimeout > 0 ? setTimeout(() => {
573
587
  child.kill();
574
588
  cleanup();
575
589
  reject(providerTimeoutError(effectiveTimeout));
576
- }, effectiveTimeout + 5000);
590
+ }, effectiveTimeout + 5000) : undefined;
577
591
  child.stdout.setEncoding('utf8');
578
592
  child.stderr.setEncoding('utf8');
579
593
  child.stdout.on('data', chunk => { stdout += chunk; });
@@ -956,7 +970,6 @@ class LLMProvider {
956
970
  const transport = this.buildProviderAdapterTransport();
957
971
  const streaming = mode === 'chat_stream';
958
972
  const reasoningState = { current: '' };
959
- let reasoningStatusEmitted = false;
960
973
  for await (const event of adapter.execute(serialized, execSignal, transport)) {
961
974
  if (event.type === 'response.started' || event.type === 'response.completed')
962
975
  continue;
@@ -964,10 +977,7 @@ class LLMProvider {
964
977
  continue;
965
978
  if (event.type === 'reasoning.summary.delta') {
966
979
  reasoningState.current += event.delta;
967
- if (!streaming && !reasoningStatusEmitted) {
968
- reasoningStatusEmitted = true;
969
- yield { type: 'status', text: '', reasoningContent: reasoningState.current };
970
- }
980
+ yield { type: 'status', text: '', reasoningContent: reasoningState.current };
971
981
  continue;
972
982
  }
973
983
  if (event.type === 'text.delta') {
@@ -1020,14 +1030,22 @@ class LLMProvider {
1020
1030
  serialized.headers['Accept'] = 'text/event-stream';
1021
1031
  const execSignal = signal ?? new AbortController().signal;
1022
1032
  const transport = this.buildProviderAdapterTransport();
1033
+ let reasoningSummary = '';
1023
1034
  for await (const event of adapter.execute(serialized, execSignal, transport)) {
1024
1035
  if (event.type === 'response.started' || event.type === 'response.completed')
1025
1036
  continue;
1026
1037
  if (event.type === 'tool_call.started' || event.type === 'tool_call.arguments.delta')
1027
1038
  continue;
1039
+ if (event.type === 'reasoning.summary.delta') {
1040
+ reasoningSummary += event.delta;
1041
+ yield { type: 'status', text: '', reasoningContent: reasoningSummary };
1042
+ continue;
1043
+ }
1028
1044
  if (event.type === 'reasoning.summary.done') {
1029
- if (event.summary)
1030
- yield { type: 'status', text: event.summary };
1045
+ if (event.summary && event.summary !== reasoningSummary) {
1046
+ reasoningSummary = event.summary;
1047
+ yield { type: 'status', text: '', reasoningContent: reasoningSummary };
1048
+ }
1031
1049
  continue;
1032
1050
  }
1033
1051
  if (event.type === 'text.delta') {
@@ -1079,7 +1097,9 @@ class LLMProvider {
1079
1097
  else
1080
1098
  signal?.addEventListener('abort', forwardAbort, { once: true });
1081
1099
  const effectiveTimeout = this.effectiveRequestTimeout(120000);
1082
- const timer = setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout);
1100
+ const timer = effectiveTimeout > 0
1101
+ ? setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout)
1102
+ : undefined;
1083
1103
  try {
1084
1104
  try {
1085
1105
  let response = await fetch(request.url, {
@@ -1228,7 +1248,9 @@ class LLMProvider {
1228
1248
  else
1229
1249
  signal?.addEventListener('abort', forwardAbort, { once: true });
1230
1250
  const effectiveTimeout = this.effectiveRequestTimeout(120000);
1231
- const timeout = setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout);
1251
+ const timeout = effectiveTimeout > 0
1252
+ ? setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout)
1253
+ : undefined;
1232
1254
  let reader = null;
1233
1255
  try {
1234
1256
  let response;
@@ -1293,6 +1315,7 @@ class LLMProvider {
1293
1315
  continue;
1294
1316
  if (delta.reasoning_content) {
1295
1317
  currentReasoningContent += delta.reasoning_content;
1318
+ yield { type: 'status', text: '', reasoningContent: currentReasoningContent };
1296
1319
  }
1297
1320
  const deltaText = this.extractTextValue(delta.content);
1298
1321
  if (deltaText) {
package/dist/main.js CHANGED
@@ -314,9 +314,9 @@ const workEventCoalescer = new workEventCoalescer_1.WorkEventCoalescer(event =>
314
314
  const workEventNoMobileCoalescer = new workEventCoalescer_1.WorkEventCoalescer(event => dispatchAgentWorkEvent(event, false));
315
315
  function broadcastAgentWorkEvent(event, mirrorToMobile = true) {
316
316
  const workEvent = event;
317
- // Text deltas are the only high-frequency event. They are coalesced at the
318
- // IPC/SSE boundary; all lifecycle/tool events retain immediate ordering.
319
- if (workEvent.type === 'text') {
317
+ // Response and thought deltas are coalesced at the IPC/SSE boundary; all
318
+ // lifecycle/tool events retain immediate ordering.
319
+ if (workEvent.type === 'text' || workEvent.type === 'thought_delta') {
320
320
  (mirrorToMobile ? workEventCoalescer : workEventNoMobileCoalescer).push(workEvent);
321
321
  return;
322
322
  }
@@ -3640,9 +3640,6 @@ else {
3640
3640
  proxyEnabled: agent.config.getBool('proxy', 'enabled'),
3641
3641
  proxyUrl: agent.config.getStr('proxy', 'url'),
3642
3642
  proxyAuth: agent.config.getStr('proxy', 'auth'),
3643
- gradientColors: agent.config.get('ui', 'gradient_colors') || [],
3644
- gradientSpeed: agent.config.getNum('ui', 'gradient_speed'),
3645
- gradientWidth: agent.config.getNum('ui', 'gradient_width'),
3646
3643
  glassAlpha: agent.config.getNum('ui', 'glass_alpha') ?? 0.85,
3647
3644
  leftPanelCollapsed: agent.config.getBool('ui', 'left_panel_collapsed'),
3648
3645
  rightPanelCollapsed: agent.config.getBool('ui', 'right_panel_collapsed'),
@@ -3809,15 +3806,6 @@ else {
3809
3806
  else {
3810
3807
  for (const [key, value] of Object.entries(cfg || {})) {
3811
3808
  switch (key) {
3812
- case 'gradientColors':
3813
- agent.config.set('ui', 'gradient_colors', value);
3814
- break;
3815
- case 'gradientSpeed':
3816
- agent.config.set('ui', 'gradient_speed', value);
3817
- break;
3818
- case 'gradientWidth':
3819
- agent.config.set('ui', 'gradient_width', value);
3820
- break;
3821
3809
  case 'glassAlpha':
3822
3810
  agent.config.set('ui', 'glass_alpha', value);
3823
3811
  break;
@@ -154,8 +154,10 @@ class ResponsesAdapter {
154
154
  if (eventType === 'response.reasoning_summary_text.delta') {
155
155
  const key = `${String(payload.item_id || '')}:${String(payload.summary_index || 0)}`;
156
156
  const delta = this.extractText(payload.delta);
157
- if (delta)
157
+ if (delta) {
158
158
  reasoningSummaries.set(key, (reasoningSummaries.get(key) || '') + delta);
159
+ yield { type: 'reasoning.summary.delta', delta };
160
+ }
159
161
  continue;
160
162
  }
161
163
  if (eventType === 'response.reasoning_summary_text.done') {
package/dist/server.js CHANGED
@@ -459,15 +459,6 @@ function applyConfigPatch(cfg) {
459
459
  return;
460
460
  for (const [key, value] of Object.entries(cfg || {})) {
461
461
  switch (key) {
462
- case 'gradientColors':
463
- agent.config.set('ui', 'gradient_colors', value);
464
- break;
465
- case 'gradientSpeed':
466
- agent.config.set('ui', 'gradient_speed', value);
467
- break;
468
- case 'gradientWidth':
469
- agent.config.set('ui', 'gradient_width', value);
470
- break;
471
462
  case 'glassAlpha':
472
463
  agent.config.set('ui', 'glass_alpha', value);
473
464
  break;
@@ -599,9 +590,6 @@ async function handleApi(req, res, body) {
599
590
  conversationPlan: agent.getConversationPlan(),
600
591
  historyMessages: agent.history.length,
601
592
  conversationLocked: agent.isConversationLocked(),
602
- gradientColors: agent.config.get('ui', 'gradient_colors') || [],
603
- gradientSpeed: agent.config.getNum('ui', 'gradient_speed'),
604
- gradientWidth: agent.config.getNum('ui', 'gradient_width'),
605
593
  glassAlpha: agent.config.getNum('ui', 'glass_alpha'),
606
594
  darkMode: agent.config.getStr('ui', 'dark_mode'),
607
595
  backgroundColor: (0, uiPreferences_1.normalizeUiBackgroundColor)(agent.config.getStr('ui', 'background_color')),
@@ -210,13 +210,8 @@ function jpegCaptureScript(outPath, boundsScript, requestedMaxWidth, requestedMa
210
210
  'Write-Output (@{ ok=$true; left=$x; top=$y; width=$w; height=$h; capture_max_width=$maxWidth; capture_max_height=$maxHeight; image_width=$imageWidth; image_height=$imageHeight; image_bytes=$fileSize; image_quality=$qualityUsed; image_available=$imageAvailable; image_mime="image/jpeg" } | ConvertTo-Json -Compress)',
211
211
  ].join('\r\n');
212
212
  }
213
- function gradientPalette(input) {
214
- const fallback = ['#00ff88', '#00ccff', '#aa44ff', '#ff4488'];
215
- const configured = Array.isArray(input) ? input : [];
216
- const raw = configured.length
217
- ? configured.map(v => String(v || '').trim()).filter(Boolean)
218
- : String(process.env.NEWMARK_COMPUTER_USE_GRADIENT || '').split(',').map(v => v.trim()).filter(Boolean);
219
- return raw.length >= 2 ? raw.slice(0, 6) : fallback;
213
+ function gradientPalette(_input) {
214
+ return ['#000000', '#ffffff', '#000000', '#ffffff'];
220
215
  }
221
216
  async function stopTakeoverOverlay() {
222
217
  const pid = takeoverOverlayPid;
@@ -239,11 +234,11 @@ async function startTakeoverOverlay(durationMs = 0, input = {}) {
239
234
  if (process.platform !== 'win32')
240
235
  return { ok: false, action: 'takeover_start', error: 'Computer Use takeover overlay is Windows-only.' };
241
236
  await stopTakeoverOverlay();
242
- lastTakeoverOverlayStyle = { colors: input.colors, speed: input.speed, width: input.width };
237
+ lastTakeoverOverlayStyle = { colors: gradientPalette(), speed: 3, width: 2 };
243
238
  const colors = gradientPalette(input.colors);
244
239
  const lifetime = Math.max(0, Math.floor(Number(durationMs || 0)));
245
- const width = Math.max(1, Math.min(24, Math.floor(Number(input.width || 2))));
246
- const speedSeconds = Math.max(0.25, Math.min(30, Number(input.speed || 2)));
240
+ const width = 2;
241
+ const speedSeconds = 3;
247
242
  const ownerPid = Math.max(0, Math.floor(Number(input.ownerPid ?? process.pid) || 0));
248
243
  const scriptPath = path.join(tempScreenshotDir(), `takeover-overlay-${timestampName()}-${crypto.randomBytes(4).toString('hex')}.ps1`);
249
244
  const script = [
@@ -901,9 +901,9 @@ class ToolExecutor {
901
901
  allowEphemeralVisionImage: context.allowEphemeralVisionImage === true,
902
902
  captureMaxWidth: Number(args.capture_max_width),
903
903
  captureMaxHeight: Number(args.capture_max_height),
904
- gradientColors: Array.isArray(args.gradient_colors) ? args.gradient_colors : (this.config.get('ui', 'gradient_colors') || []),
905
- gradientSpeed: args.gradient_speed !== undefined ? Number(args.gradient_speed) : this.config.getNum('ui', 'gradient_speed'),
906
- gradientWidth: args.gradient_width !== undefined ? Number(args.gradient_width) : this.config.getNum('ui', 'gradient_width'),
904
+ gradientColors: Array.isArray(args.gradient_colors) ? args.gradient_colors : undefined,
905
+ gradientSpeed: args.gradient_speed !== undefined ? Number(args.gradient_speed) : undefined,
906
+ gradientWidth: args.gradient_width !== undefined ? Number(args.gradient_width) : undefined,
907
907
  invocation: context.invocation,
908
908
  ownerId: owner,
909
909
  includeRawUi: args.include_raw_ui === true,
@@ -108,10 +108,10 @@ try {
108
108
  --radius-full: 9999px;
109
109
 
110
110
  /* Marquee gradient */
111
- --g1: #00ff88;
112
- --g2: #00ccff;
113
- --g3: #aa44ff;
114
- --g4: #ff4488;
111
+ --g1: #000000;
112
+ --g2: #ffffff;
113
+ --g3: #000000;
114
+ --g4: #ffffff;
115
115
  --marquee-speed: 3s;
116
116
  --marquee-width: 2px;
117
117
 
@@ -6182,9 +6182,6 @@ var state = {
6182
6182
  conversationArchiveRefreshTimer: null,
6183
6183
  conversationArchiveActiveSyncTimer: null,
6184
6184
  nextConversationSequence: 0,
6185
- configGradientColors: ['#00ff88', '#00ccff', '#aa44ff', '#ff4488'],
6186
- configGradientSpeed: 3,
6187
- configGradientWidth: 2,
6188
6185
  inputMode: 'guide',
6189
6186
  theme: 'dark',
6190
6187
  backgroundColor: '',
@@ -9896,7 +9893,7 @@ function publicWorkEvent(event) {
9896
9893
  var content = String(event && event.content || '');
9897
9894
  var toolArgs = String(event && event.toolArgs || '');
9898
9895
  if (/<think(?:\s|>)/i.test(content) || /<\/think>/i.test(content) || /<\/?think\b|(?:reasoning_content|thinking_delta)\s*[::]/i.test(toolArgs)) return false;
9899
- return ['start', 'text', 'response', 'final_response', 'status', 'tool_call', 'tool_result', 'thought', 'thought_result', 'guide', 'guide_accepted', 'guide_applied', 'guide_deferred', 'guide_rejected', 'done', 'error', 'interrupted', 'force_interrupted'].indexOf(type) >= 0;
9896
+ return ['start', 'text', 'response', 'final_response', 'status', 'tool_call', 'tool_result', 'thought', 'thought_delta', 'thought_result', 'guide', 'guide_accepted', 'guide_applied', 'guide_deferred', 'guide_rejected', 'done', 'error', 'interrupted', 'force_interrupted'].indexOf(type) >= 0;
9900
9897
  }
9901
9898
 
9902
9899
  function publicToolNameForUi(value) {
@@ -10568,6 +10565,16 @@ function renderWorkRunEvents(run, includeGuides) {
10568
10565
  }
10569
10566
  if (!rawEvent) continue;
10570
10567
  }
10568
+ if (rawType === 'thought_delta') {
10569
+ for (var thoughtDeltaIndex = events.length - 1; thoughtDeltaIndex >= 0; thoughtDeltaIndex--) {
10570
+ var liveThought = events[thoughtDeltaIndex];
10571
+ if (String(liveThought && liveThought.type || '').toLowerCase() !== 'thought' || liveThought.completed) continue;
10572
+ events[thoughtDeltaIndex] = Object.assign({}, liveThought, { content: String(liveThought.content || '') + String(rawEvent.content || '') });
10573
+ rawEvent = null;
10574
+ break;
10575
+ }
10576
+ if (!rawEvent) continue;
10577
+ }
10571
10578
  events.push(rawEvent);
10572
10579
  }
10573
10580
  flushPublicText();
@@ -10786,6 +10793,16 @@ function applyAgentWorkEventToRun(event) {
10786
10793
  recordGuideUiMessage(event, target);
10787
10794
  }
10788
10795
  if (publicWorkEvent(event) && type !== 'start') {
10796
+ if (type === 'thought_delta') {
10797
+ for (var liveThoughtIndex = run.events.length - 1; liveThoughtIndex >= 0; liveThoughtIndex--) {
10798
+ var liveThoughtEvent = run.events[liveThoughtIndex];
10799
+ if (String(liveThoughtEvent.type || '').toLowerCase() !== 'thought' || liveThoughtEvent.completed) continue;
10800
+ run.events[liveThoughtIndex] = Object.assign({}, liveThoughtEvent, {
10801
+ content: String(liveThoughtEvent.content || '') + String(event.content || '')
10802
+ });
10803
+ break;
10804
+ }
10805
+ } else {
10789
10806
  var incomingGuideKey = guideWorkEventKey(event);
10790
10807
  if (incomingGuideKey) {
10791
10808
  for (var guideEventIndex = run.events.length - 1; guideEventIndex >= 0; guideEventIndex--) {
@@ -10805,6 +10822,7 @@ function applyAgentWorkEventToRun(event) {
10805
10822
  var eventId = String(event.id || [event.sequence || '', type, event.timestamp || '', event.content || ''].join('|'));
10806
10823
  if (!run.events.some(function(item) { return String(item.id || '') === eventId; })) run.events.push(Object.assign({}, event, { id: eventId }));
10807
10824
  run.events.sort(compareConversationWorkEvents);
10825
+ }
10808
10826
  }
10809
10827
  run.sequence = Math.max(Number(run.sequence || 0), Number(event.sequence || 0));
10810
10828
  if (type === 'done') { run.status = 'completed'; run.endedAt = event.endedAt || event.timestampIso || new Date().toISOString(); if (run.userToggled !== true) run.expanded = false; }
@@ -11366,7 +11384,13 @@ function cacheAgentWorkEvent(event) {
11366
11384
  var id = eventRuntimeKey(event);
11367
11385
  if (!state.agentWorkEventsByConversation) state.agentWorkEventsByConversation = {};
11368
11386
  if (!state.agentWorkEventsByConversation[id]) state.agentWorkEventsByConversation[id] = [];
11369
- state.agentWorkEventsByConversation[id].push(event);
11387
+ var cached = state.agentWorkEventsByConversation[id];
11388
+ var previous = cached.length ? cached[cached.length - 1] : null;
11389
+ if (event.type === 'thought_delta' && previous && previous.type === 'thought_delta' && String(previous.runId || '') === String(event.runId || '')) {
11390
+ previous.content = String(previous.content || '') + String(event.content || '');
11391
+ } else {
11392
+ cached.push(event);
11393
+ }
11370
11394
  var limit = Number(state.agentWorkEventLimit || 240);
11371
11395
  if (state.agentWorkEventsByConversation[id].length > limit) {
11372
11396
  state.agentWorkEventsByConversation[id] = state.agentWorkEventsByConversation[id].slice(-limit);
@@ -15652,7 +15676,6 @@ function renderGeneralSettings() {
15652
15676
  for (var i = 0; i < themeOpts.length; i++) {
15653
15677
  themeHtml += '<option value="' + themeOpts[i].v + '"' + (state.theme === themeOpts[i].v ? ' selected' : '') + '>' + themeOpts[i].l + '</option>';
15654
15678
  }
15655
- var gradColors = state.configGradientColors || ['#ff6b6b','#ffd93d','#6bcb77','#4d96ff'];
15656
15679
  var backgroundColor = /^#[0-9a-f]{6}$/i.test(String(state.backgroundColor || ''))
15657
15680
  ? state.backgroundColor
15658
15681
  : (state.theme === 'light' ? '#F0F2F8' : '#0A0A1A');
@@ -15721,16 +15744,6 @@ function renderGeneralSettings() {
15721
15744
  '<div class="setting-desc" id="glass-desc" aria-live="polite">' + esc(glassDescription) + '</div></div>' +
15722
15745
  '</div>' +
15723
15746
  '<div class="setting-row">' +
15724
- '<span class="setting-label">' + esc(t('settings.gradient')) + '</span>' +
15725
- '<div class="setting-control" style="flex-wrap:wrap;gap:4px;">' +
15726
- '<input type="color" value="' + gradColors[0] + '" onchange="window.setGradientColor(0,this.value)" style="width:36px;height:28px;padding:0;border:1px solid var(--border);border-radius:var(--radius-sm);background:none;cursor:pointer;">' +
15727
- '<input type="color" value="' + gradColors[1] + '" onchange="window.setGradientColor(1,this.value)" style="width:36px;height:28px;padding:0;border:1px solid var(--border);border-radius:var(--radius-sm);background:none;cursor:pointer;">' +
15728
- '<input type="color" value="' + gradColors[2] + '" onchange="window.setGradientColor(2,this.value)" style="width:36px;height:28px;padding:0;border:1px solid var(--border);border-radius:var(--radius-sm);background:none;cursor:pointer;">' +
15729
- '<input type="color" value="' + gradColors[3] + '" onchange="window.setGradientColor(3,this.value)" style="width:36px;height:28px;padding:0;border:1px solid var(--border);border-radius:var(--radius-sm);background:none;cursor:pointer;">' +
15730
- '<div class="setting-desc" style="width:100%;">' + esc(t('settings.speed')) + ': <input type="range" min="1" max="10" value="' + (state.configGradientSpeed || 3) + '" oninput="window.setGradientSpeed(this.value)" style="width:60px;vertical-align:middle;">' +
15731
- ' ' + esc(t('settings.width')) + ': <input type="range" min="1" max="6" value="' + (state.configGradientWidth || 2) + '" oninput="window.setGradientWidth(this.value)" style="width:60px;vertical-align:middle;"></div></div>' +
15732
- '</div>' +
15733
- '<div class="setting-row">' +
15734
15747
  '<span class="setting-label">' + esc(t('settings.inputMode')) + '</span>' +
15735
15748
  '<div class="setting-control"><select onchange="window.setInputMode(this.value)">' +
15736
15749
  '<option value="guide"' + (state.inputMode === 'guide' ? ' selected' : '') + '>' + esc(t('input.guide')) + '</option>' +
@@ -16284,25 +16297,6 @@ window.commitGlassOpacity = function(value) {
16284
16297
  if (api.saveConfig) api.saveConfig({ glassAlpha: presentation.alpha }).catch(function(){});
16285
16298
  };
16286
16299
 
16287
- window.setGradientColor = function(idx, color) {
16288
- if (!state.configGradientColors) state.configGradientColors = ['#ff6b6b','#ffd93d','#6bcb77','#4d96ff'];
16289
- state.configGradientColors[idx] = color;
16290
- updateMarqueeFromConfig();
16291
- api.saveConfig({gradientColors: state.configGradientColors});
16292
- };
16293
-
16294
- window.setGradientSpeed = function(v) {
16295
- state.configGradientSpeed = parseInt(v);
16296
- updateMarqueeFromConfig();
16297
- api.saveConfig({gradientSpeed: state.configGradientSpeed});
16298
- };
16299
-
16300
- window.setGradientWidth = function(v) {
16301
- state.configGradientWidth = parseInt(v);
16302
- updateMarqueeFromConfig();
16303
- api.saveConfig({gradientWidth: state.configGradientWidth});
16304
- };
16305
-
16306
16300
  window.setDialogStyle = function(v) {
16307
16301
  state.dialogStyle = v;
16308
16302
  api.saveConfig({ dialogStyle: v });
@@ -22388,27 +22382,12 @@ window.ensureFlowsLoaded = function(options) {
22388
22382
  return state._flowLoadPromise;
22389
22383
  };
22390
22384
 
22391
- // === Update Marquee ===
22392
22385
  var marqueeRAF = null;
22393
- function updateMarqueeFromConfig() {
22394
- var root = document.documentElement;
22395
- var colors = state.configGradientColors;
22396
- if (colors && colors.length >= 4) {
22397
- root.style.setProperty('--g1', colors[0]);
22398
- root.style.setProperty('--g2', colors[1]);
22399
- root.style.setProperty('--g3', colors[2]);
22400
- root.style.setProperty('--g4', colors[3]);
22401
- }
22402
- root.style.setProperty('--marquee-speed', (state.configGradientSpeed || 2) + 's');
22403
- root.style.setProperty('--marquee-width', (state.configGradientWidth || 2) + 'px');
22404
- }
22405
-
22406
22386
  // JS-driven marquee fallback for browsers without @property support
22407
22387
  function startMarqueeJS() {
22408
22388
  if (marqueeRAF) return;
22409
22389
  var root = document.documentElement;
22410
22390
  var angle = 0;
22411
- var speed = (state.configGradientSpeed || 3) * 60;
22412
22391
  function tick() {
22413
22392
  angle = (angle + 1) % 360;
22414
22393
  root.style.setProperty('--marquee-angle', angle + 'deg');
@@ -23243,9 +23222,6 @@ function schedulePostStartupUiRendering() {
23243
23222
  state.fontFamily = normalizeUiFontFamilyClient(s.fontFamily || '');
23244
23223
  state.glassLevel = glassPresentationForOpacity((s.glassAlpha ?? 0.85) * 100).opacityPercent;
23245
23224
  state.models = s.models || [];
23246
- if (s.gradientColors && s.gradientColors.length) state.configGradientColors = s.gradientColors;
23247
- if (s.gradientSpeed) state.configGradientSpeed = s.gradientSpeed;
23248
- if (s.gradientWidth) state.configGradientWidth = s.gradientWidth;
23249
23225
  applySavedLayoutState({
23250
23226
  leftCollapsed: s.leftPanelCollapsed,
23251
23227
  rightCollapsed: s.rightPanelCollapsed,
@@ -23329,7 +23305,6 @@ function schedulePostStartupUiRendering() {
23329
23305
  });
23330
23306
  }
23331
23307
 
23332
- updateMarqueeFromConfig();
23333
23308
  window.startRemoteTouchStatusPolling();
23334
23309
 
23335
23310
  // Populate selects
@@ -327676,7 +327676,9 @@ var ConfigManager = class {
327676
327676
  this.backupConfig(cp, "invalid-shape");
327677
327677
  return this.writeRecoveredConfig(cp);
327678
327678
  }
327679
- if (migrateProviderIdsInConfig(normalized)) {
327679
+ const providerIdsMigrated = migrateProviderIdsInConfig(normalized);
327680
+ const marqueeConfigRemoved = removeDeprecatedMarqueeConfig(normalized);
327681
+ if (providerIdsMigrated || marqueeConfigRemoved) {
327680
327682
  try {
327681
327683
  if (!this.readOnly) fs3.writeFileSync(cp, JSON.stringify(normalized, null, 2), "utf-8");
327682
327684
  } catch {
@@ -327995,6 +327997,18 @@ function normalizeConfigShape(raw, withDefaults) {
327995
327997
  }
327996
327998
  return base2;
327997
327999
  }
328000
+ function removeDeprecatedMarqueeConfig(config) {
328001
+ const ui = config.ui;
328002
+ if (!ui) return false;
328003
+ let changed = false;
328004
+ for (const key3 of ["gradient_colors", "gradient_speed", "gradient_width"]) {
328005
+ if (Object.prototype.hasOwnProperty.call(ui, key3)) {
328006
+ delete ui[key3];
328007
+ changed = true;
328008
+ }
328009
+ }
328010
+ return changed;
328011
+ }
327998
328012
  function isConfigEntry(value) {
327999
328013
  return !!value && typeof value === "object" && !Array.isArray(value) && Object.prototype.hasOwnProperty.call(value, "value");
328000
328014
  }
@@ -328362,9 +328376,6 @@ function defaultConfig() {
328362
328376
  auto_download: { _description: "Auto-download skills", _type: "choice", _values: ["aggressive", "conservative", "disabled"], value: "conservative" }
328363
328377
  },
328364
328378
  ui: {
328365
- gradient_colors: { _description: "Gradient colors (hex)", _type: "array", value: ["#00ff88", "#00ccff", "#aa44ff", "#ff4488"] },
328366
- gradient_speed: { _description: "Animation speed 1-5", _type: "range", _min: 1, _max: 5, value: 2 },
328367
- gradient_width: { _description: "Border width", _type: "integer", _min: 1, _max: 4, value: 2 },
328368
328379
  glass_alpha: { _description: "Glass opacity", _type: "range", _min: 0, _max: 1, value: 0.85 },
328369
328380
  show_mode_label: { _description: "Show mode on hover", _type: "boolean", value: true },
328370
328381
  left_panel_collapsed: { _description: "Left panel collapsed", _type: "boolean", value: false },
@@ -329205,7 +329216,10 @@ var ResponsesAdapter = class {
329205
329216
  if (eventType === "response.reasoning_summary_text.delta") {
329206
329217
  const key3 = `${String(payload.item_id || "")}:${String(payload.summary_index || 0)}`;
329207
329218
  const delta = this.extractText(payload.delta);
329208
- if (delta) reasoningSummaries.set(key3, (reasoningSummaries.get(key3) || "") + delta);
329219
+ if (delta) {
329220
+ reasoningSummaries.set(key3, (reasoningSummaries.get(key3) || "") + delta);
329221
+ yield { type: "reasoning.summary.delta", delta };
329222
+ }
329209
329223
  continue;
329210
329224
  }
329211
329225
  if (eventType === "response.reasoning_summary_text.done") {
@@ -329397,7 +329411,7 @@ function createProviderAdapter(providerId, apiMode) {
329397
329411
  }
329398
329412
 
329399
329413
  // src/llm/provider.ts
329400
- var DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS = 9e4;
329414
+ var DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS = 0;
329401
329415
  var MIN_PROVIDER_REQUEST_TIMEOUT_MS = 50;
329402
329416
  function providerTimeoutError(timeoutMs) {
329403
329417
  const error = new Error(`Provider request timed out after ${timeoutMs}ms`);
@@ -329458,11 +329472,13 @@ var LLMProvider = class _LLMProvider {
329458
329472
  static powershellTransport = null;
329459
329473
  temperatureUnsupported = /* @__PURE__ */ new Set();
329460
329474
  effectiveRequestTimeout(timeoutMs) {
329461
- const requested = Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS;
329462
- const configured = Number.isFinite(this.requestTimeoutMs) && this.requestTimeoutMs > 0 ? this.requestTimeoutMs : DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS;
329475
+ const requested = Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : 0;
329476
+ const configured = Number.isFinite(this.requestTimeoutMs) && this.requestTimeoutMs > 0 ? this.requestTimeoutMs : 0;
329477
+ if (requested <= 0 || configured <= 0) return 0;
329463
329478
  return Math.max(MIN_PROVIDER_REQUEST_TIMEOUT_MS, Math.min(requested, configured));
329464
329479
  }
329465
329480
  async withRequestTimeout(promise, timeoutMs, signal) {
329481
+ if (timeoutMs <= 0) return await abortable(promise, signal);
329466
329482
  let timer;
329467
329483
  const timeoutPromise = new Promise((_3, reject) => {
329468
329484
  timer = setTimeout(() => reject(providerTimeoutError(timeoutMs)), timeoutMs);
@@ -329662,7 +329678,7 @@ var LLMProvider = class _LLMProvider {
329662
329678
  const forwardAbort = () => abort.abort(signal?.reason);
329663
329679
  if (signal?.aborted) forwardAbort();
329664
329680
  else signal?.addEventListener("abort", forwardAbort, { once: true });
329665
- const timer = setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout);
329681
+ const timer = effectiveTimeout > 0 ? setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout) : void 0;
329666
329682
  try {
329667
329683
  const response = await fetch(url, {
329668
329684
  method: "POST",
@@ -329691,7 +329707,7 @@ var LLMProvider = class _LLMProvider {
329691
329707
  async getJsonWithFetchFallback(url, headers, timeoutMs = 3e4) {
329692
329708
  const effectiveTimeout = this.effectiveRequestTimeout(timeoutMs);
329693
329709
  const abort = new AbortController();
329694
- const timer = setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout);
329710
+ const timer = effectiveTimeout > 0 ? setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout) : void 0;
329695
329711
  try {
329696
329712
  const response = await fetch(url, { method: "GET", headers, signal: abort.signal });
329697
329713
  return response;
@@ -329765,9 +329781,11 @@ var LLMProvider = class _LLMProvider {
329765
329781
  else fail(new Error("Node HTTP response closed before completion"));
329766
329782
  });
329767
329783
  });
329768
- req.setTimeout(effectiveTimeout, () => {
329769
- req.destroy(providerTimeoutError(effectiveTimeout));
329770
- });
329784
+ if (effectiveTimeout > 0) {
329785
+ req.setTimeout(effectiveTimeout, () => {
329786
+ req.destroy(providerTimeoutError(effectiveTimeout));
329787
+ });
329788
+ }
329771
329789
  req.on("error", reject);
329772
329790
  const onAbort = () => req.destroy(abortFailure(signal));
329773
329791
  if (signal?.aborted) onAbort();
@@ -329816,7 +329834,7 @@ var LLMProvider = class _LLMProvider {
329816
329834
  " $raw = $headerJson | ConvertFrom-Json",
329817
329835
  " foreach ($p in $raw.PSObject.Properties) { $headers[$p.Name] = [string]$p.Value }",
329818
329836
  "}",
329819
- `'$params = @{ Uri = $uri; Method = $method; Headers = $headers; UseBasicParsing = $true; TimeoutSec = ${Math.max(1, Math.ceil(effectiveTimeout / 1e3))} }`,
329837
+ effectiveTimeout > 0 ? `$params = @{ Uri = $uri; Method = $method; Headers = $headers; UseBasicParsing = $true; TimeoutSec = ${Math.ceil(effectiveTimeout / 1e3)} }` : "$params = @{ Uri = $uri; Method = $method; Headers = $headers; UseBasicParsing = $true }",
329820
329838
  'if ($method -eq "POST") { $params["Body"] = $bodyJson }',
329821
329839
  'if ($method -eq "POST") { $params["ContentType"] = "application/json; charset=utf-8" }',
329822
329840
  "$resp = Invoke-WebRequest @params",
@@ -329845,11 +329863,11 @@ var LLMProvider = class _LLMProvider {
329845
329863
  };
329846
329864
  if (signal?.aborted) onAbort();
329847
329865
  else signal?.addEventListener("abort", onAbort, { once: true });
329848
- const timer = setTimeout(() => {
329866
+ const timer = effectiveTimeout > 0 ? setTimeout(() => {
329849
329867
  child.kill();
329850
329868
  cleanup();
329851
329869
  reject(providerTimeoutError(effectiveTimeout));
329852
- }, effectiveTimeout + 5e3);
329870
+ }, effectiveTimeout + 5e3) : void 0;
329853
329871
  child.stdout.setEncoding("utf8");
329854
329872
  child.stderr.setEncoding("utf8");
329855
329873
  child.stdout.on("data", (chunk) => {
@@ -330199,16 +330217,12 @@ ${responsePath}
330199
330217
  const transport = this.buildProviderAdapterTransport();
330200
330218
  const streaming = mode === "chat_stream";
330201
330219
  const reasoningState = { current: "" };
330202
- let reasoningStatusEmitted = false;
330203
330220
  for await (const event of adapter.execute(serialized, execSignal, transport)) {
330204
330221
  if (event.type === "response.started" || event.type === "response.completed") continue;
330205
330222
  if (event.type === "tool_call.started" || event.type === "tool_call.arguments.delta") continue;
330206
330223
  if (event.type === "reasoning.summary.delta") {
330207
330224
  reasoningState.current += event.delta;
330208
- if (!streaming && !reasoningStatusEmitted) {
330209
- reasoningStatusEmitted = true;
330210
- yield { type: "status", text: "", reasoningContent: reasoningState.current };
330211
- }
330225
+ yield { type: "status", text: "", reasoningContent: reasoningState.current };
330212
330226
  continue;
330213
330227
  }
330214
330228
  if (event.type === "text.delta") {
@@ -330260,11 +330274,20 @@ ${responsePath}
330260
330274
  serialized.headers["Accept"] = "text/event-stream";
330261
330275
  const execSignal = signal ?? new AbortController().signal;
330262
330276
  const transport = this.buildProviderAdapterTransport();
330277
+ let reasoningSummary = "";
330263
330278
  for await (const event of adapter.execute(serialized, execSignal, transport)) {
330264
330279
  if (event.type === "response.started" || event.type === "response.completed") continue;
330265
330280
  if (event.type === "tool_call.started" || event.type === "tool_call.arguments.delta") continue;
330281
+ if (event.type === "reasoning.summary.delta") {
330282
+ reasoningSummary += event.delta;
330283
+ yield { type: "status", text: "", reasoningContent: reasoningSummary };
330284
+ continue;
330285
+ }
330266
330286
  if (event.type === "reasoning.summary.done") {
330267
- if (event.summary) yield { type: "status", text: event.summary };
330287
+ if (event.summary && event.summary !== reasoningSummary) {
330288
+ reasoningSummary = event.summary;
330289
+ yield { type: "status", text: "", reasoningContent: reasoningSummary };
330290
+ }
330268
330291
  continue;
330269
330292
  }
330270
330293
  if (event.type === "text.delta") {
@@ -330313,7 +330336,7 @@ ${responsePath}
330313
330336
  if (signal?.aborted) forwardAbort();
330314
330337
  else signal?.addEventListener("abort", forwardAbort, { once: true });
330315
330338
  const effectiveTimeout = this.effectiveRequestTimeout(12e4);
330316
- const timer = setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout);
330339
+ const timer = effectiveTimeout > 0 ? setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout) : void 0;
330317
330340
  try {
330318
330341
  try {
330319
330342
  let response2 = await fetch(request.url, {
@@ -330458,7 +330481,7 @@ ${responsePath}
330458
330481
  if (signal?.aborted) forwardAbort();
330459
330482
  else signal?.addEventListener("abort", forwardAbort, { once: true });
330460
330483
  const effectiveTimeout = this.effectiveRequestTimeout(12e4);
330461
- const timeout = setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout);
330484
+ const timeout = effectiveTimeout > 0 ? setTimeout(() => abort.abort(providerTimeoutError(effectiveTimeout)), effectiveTimeout) : void 0;
330462
330485
  let reader = null;
330463
330486
  try {
330464
330487
  let response;
@@ -330513,6 +330536,7 @@ ${responsePath}
330513
330536
  if (!delta) continue;
330514
330537
  if (delta.reasoning_content) {
330515
330538
  currentReasoningContent += delta.reasoning_content;
330539
+ yield { type: "status", text: "", reasoningContent: currentReasoningContent };
330516
330540
  }
330517
330541
  const deltaText = this.extractTextValue(delta.content);
330518
330542
  if (deltaText) {
@@ -333766,11 +333790,8 @@ function jpegCaptureScript(outPath, boundsScript, requestedMaxWidth, requestedMa
333766
333790
  'Write-Output (@{ ok=$true; left=$x; top=$y; width=$w; height=$h; capture_max_width=$maxWidth; capture_max_height=$maxHeight; image_width=$imageWidth; image_height=$imageHeight; image_bytes=$fileSize; image_quality=$qualityUsed; image_available=$imageAvailable; image_mime="image/jpeg" } | ConvertTo-Json -Compress)'
333767
333791
  ].join("\r\n");
333768
333792
  }
333769
- function gradientPalette(input2) {
333770
- const fallback = ["#00ff88", "#00ccff", "#aa44ff", "#ff4488"];
333771
- const configured = Array.isArray(input2) ? input2 : [];
333772
- const raw = configured.length ? configured.map((v) => String(v || "").trim()).filter(Boolean) : String(process.env.NEWMARK_COMPUTER_USE_GRADIENT || "").split(",").map((v) => v.trim()).filter(Boolean);
333773
- return raw.length >= 2 ? raw.slice(0, 6) : fallback;
333793
+ function gradientPalette(_input) {
333794
+ return ["#000000", "#ffffff", "#000000", "#ffffff"];
333774
333795
  }
333775
333796
  async function stopTakeoverOverlay() {
333776
333797
  const pid = takeoverOverlayPid;
@@ -333792,11 +333813,11 @@ async function stopTakeoverOverlay() {
333792
333813
  async function startTakeoverOverlay(durationMs = 0, input2 = {}) {
333793
333814
  if (process.platform !== "win32") return { ok: false, action: "takeover_start", error: "Computer Use takeover overlay is Windows-only." };
333794
333815
  await stopTakeoverOverlay();
333795
- lastTakeoverOverlayStyle = { colors: input2.colors, speed: input2.speed, width: input2.width };
333816
+ lastTakeoverOverlayStyle = { colors: gradientPalette(), speed: 3, width: 2 };
333796
333817
  const colors = gradientPalette(input2.colors);
333797
333818
  const lifetime = Math.max(0, Math.floor(Number(durationMs || 0)));
333798
- const width = Math.max(1, Math.min(24, Math.floor(Number(input2.width || 2))));
333799
- const speedSeconds = Math.max(0.25, Math.min(30, Number(input2.speed || 2)));
333819
+ const width = 2;
333820
+ const speedSeconds = 3;
333800
333821
  const ownerPid = Math.max(0, Math.floor(Number(input2.ownerPid ?? process.pid) || 0));
333801
333822
  const scriptPath = path9.join(tempScreenshotDir(), `takeover-overlay-${timestampName()}-${crypto6.randomBytes(4).toString("hex")}.ps1`);
333802
333823
  const script = [
@@ -337563,9 +337584,9 @@ var ToolExecutor = class {
337563
337584
  allowEphemeralVisionImage: context.allowEphemeralVisionImage === true,
337564
337585
  captureMaxWidth: Number(args.capture_max_width),
337565
337586
  captureMaxHeight: Number(args.capture_max_height),
337566
- gradientColors: Array.isArray(args.gradient_colors) ? args.gradient_colors : this.config.get("ui", "gradient_colors") || [],
337567
- gradientSpeed: args.gradient_speed !== void 0 ? Number(args.gradient_speed) : this.config.getNum("ui", "gradient_speed"),
337568
- gradientWidth: args.gradient_width !== void 0 ? Number(args.gradient_width) : this.config.getNum("ui", "gradient_width"),
337587
+ gradientColors: Array.isArray(args.gradient_colors) ? args.gradient_colors : void 0,
337588
+ gradientSpeed: args.gradient_speed !== void 0 ? Number(args.gradient_speed) : void 0,
337589
+ gradientWidth: args.gradient_width !== void 0 ? Number(args.gradient_width) : void 0,
337569
337590
  invocation: context.invocation,
337570
337591
  ownerId: owner,
337571
337592
  includeRawUi: args.include_raw_ui === true,
@@ -340966,6 +340987,7 @@ async function runAgentKernel(agent) {
340966
340987
  currentAgent.emitWorkEvent({ type: "thought", content: "" });
340967
340988
  }
340968
340989
  if (delta) {
340990
+ currentAgent.emitWorkEvent({ type: "thought_delta", content: delta });
340969
340991
  stream2.push({ type: "thinking_delta", contentIndex, delta, partial: assistantMessage2(model, thinking ? [{ type: "text", text }] : [], "stop") });
340970
340992
  }
340971
340993
  }
@@ -346697,7 +346719,7 @@ ${String(event.toolArgs || "")}`;
346697
346719
  id: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
346698
346720
  conversationId: input2.conversationId || this.activeConversationId || "default",
346699
346721
  type: publishedType,
346700
- content: isToolEvent ? this.publicToolEventContent(publishedType, toolName) : input2.type === "text" ? this.sanitizeAssistantStreamingOutput(input2.content || "") : this.sanitizePublicWorkContent(input2.content || ""),
346722
+ content: isToolEvent ? this.publicToolEventContent(publishedType, toolName) : input2.type === "text" || input2.type === "thought_delta" ? this.sanitizeAssistantStreamingOutput(input2.content || "") : this.sanitizePublicWorkContent(input2.content || ""),
346701
346723
  mode: input2.mode || this.modeName(),
346702
346724
  model: input2.model || this.model,
346703
346725
  timestamp: input2.timestamp || this.nowLabel(),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "newmark-agent",
3
3
  "productName": "Newmark Agent",
4
- "version": "0.5.1",
4
+ "version": "0.5.3",
5
5
  "description": "Newmark Agent — Portable AI coding agent with rich GUI and CLI (TypeScript)",
6
6
  "homepage": "https://github.com/positer/Newmark-Agent",
7
7
  "repository": {