newmark-agent 0.4.8 → 0.4.9

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.
@@ -340987,7 +340987,7 @@ async function runAgentKernel(agent) {
340987
340987
  return;
340988
340988
  }
340989
340989
  const publicError = normalizePublicProviderError(error, [currentAgent.activeModelConfig()?.api_key]);
340990
- if (/\b402\b|insufficient balance|insufficient funds|payment required|余额不足/i.test(publicError)) {
340990
+ if (/\b402\b|insufficient balance|insufficient funds|payment required|insufficient[_ -]?quota|quota (?:exceeded|exhausted)|credit(?:s| balance)? (?:exhausted|depleted)|billing hard limit|budget exhausted|余额不足|额度不足|配额(?:不足|耗尽|超限)/i.test(publicError)) {
340991
340991
  currentAgent.noteProviderBalanceFailure();
340992
340992
  }
340993
340993
  const final = assistantMessage2(model, [{ type: "text", text: `[Error] ${publicError}` }], "error");
@@ -343055,8 +343055,8 @@ function classifyRouteFailure(error) {
343055
343055
  if (statusCode === 400 || /bad request|invalid parameter|invalid request/i.test(text)) {
343056
343056
  return { type: "invalid_request", retryable: false, switchAllowed: false, statusCode };
343057
343057
  }
343058
- if (statusCode === 402 || /insufficient balance|insufficient funds|payment required|余额不足/i.test(text)) {
343059
- return { type: "balance_exhausted", retryable: false, switchAllowed: false, statusCode: 402 };
343058
+ if (statusCode === 402 || /insufficient balance|insufficient funds|payment required|insufficient[_ -]?quota|quota (?:exceeded|exhausted)|credit(?:s| balance)? (?:exhausted|depleted)|billing hard limit|budget exhausted|余额不足|额度不足|配额(?:不足|耗尽|超限)/i.test(text)) {
343059
+ return { type: "balance_exhausted", retryable: false, switchAllowed: true, statusCode: statusCode || 402 };
343060
343060
  }
343061
343061
  if (statusCode === 429 || /rate limit|too many requests/i.test(text)) {
343062
343062
  return { type: "rate_limited", retryable: true, switchAllowed: true, statusCode: 429, retryAfterMs };
@@ -343194,13 +343194,13 @@ var AutoRouter = class {
343194
343194
  }
343195
343195
  planAttempts(decision, candidates, failure) {
343196
343196
  const current = decision.resolvedDeployment;
343197
- if (!current || !failure.error.retryable || !failure.error.switchAllowed || failure.streamCommitted || failure.sideEffectCommitted) return [];
343197
+ if (!current || !failure.error.switchAllowed || failure.streamCommitted || failure.sideEffectCommitted) return [];
343198
343198
  const remainingAttempts = Math.max(0, 3 - decision.attempts.length);
343199
343199
  if (!remainingAttempts) return [];
343200
343200
  const attempts = [];
343201
343201
  const retryDelayMs = failure.error.retryAfterMs ?? 250;
343202
343202
  const alreadyRetriedCurrent = decision.attempts.some((attempt) => attempt.kind === "retry_same_deployment" && sameDeployment(attempt.deployment, current));
343203
- if (!alreadyRetriedCurrent && retryDelayMs <= (decision.retryBudgetMs ?? 5e3)) {
343203
+ if (failure.error.retryable && !alreadyRetriedCurrent && retryDelayMs <= (decision.retryBudgetMs ?? 5e3)) {
343204
343204
  attempts.push({
343205
343205
  deployment: { ...current },
343206
343206
  kind: "retry_same_deployment",
@@ -343221,11 +343221,16 @@ var AutoRouter = class {
343221
343221
  const eligible = candidates.filter((candidate) => candidate.enabled && inScope(candidate.deployment, scope) && inSubset(candidate.deployment, subset) && !sameDeployment(candidate.deployment, current) && !attemptedDeployments.some((attempted) => sameDeployment(candidate.deployment, attempted)) && validationEligible(candidate, now2).length === 0 && this.passedInitialHardFilters(decision, candidate) && this.circuitState(candidate.deployment, now2, false) !== "open");
343222
343222
  const equivalent = currentGroup ? eligible.find((candidate) => candidate.deployment.logicalModelGroupId === currentGroup && !candidate.fallbackOnly) : void 0;
343223
343223
  const fallback = eligible.find((candidate) => candidate.fallbackOnly);
343224
- for (const next of [equivalent, fallback]) {
343224
+ const rankedAlternates = decision.rankedCandidates.map((ranked) => eligible.find((candidate) => sameDeployment(candidate.deployment, ranked.deployment))).filter((candidate) => !!candidate && candidate !== equivalent && candidate !== fallback && !candidate.fallbackOnly);
343225
+ for (const candidate of eligible) {
343226
+ if (candidate === equivalent || candidate === fallback || candidate.fallbackOnly || rankedAlternates.some((existing) => sameDeployment(existing.deployment, candidate.deployment))) continue;
343227
+ rankedAlternates.push(candidate);
343228
+ }
343229
+ for (const next of [equivalent, fallback, ...rankedAlternates]) {
343225
343230
  if (!next || attempts.length >= 2) continue;
343226
343231
  attempts.push({
343227
343232
  deployment: { ...next.deployment },
343228
- kind: next === equivalent ? "equivalent_deployment" : "fallback_model",
343233
+ kind: next === equivalent ? "equivalent_deployment" : next === fallback ? "fallback_model" : "alternate_model",
343229
343234
  status: "planned",
343230
343235
  errorType: failure.error.type,
343231
343236
  streamCommitted: false,
@@ -343468,7 +343473,7 @@ function percentile(values, fraction) {
343468
343473
  }
343469
343474
  function failureFromType(type) {
343470
343475
  const retryable = type === "timeout" || type === "rate_limited" || type === "transport" || type === "server_error" || type === "empty_response";
343471
- return { type, retryable, switchAllowed: retryable };
343476
+ return { type, retryable, switchAllowed: retryable || type === "balance_exhausted" };
343472
343477
  }
343473
343478
 
343474
343479
  // src/context/services/agent-context-manager.ts
@@ -345574,7 +345579,9 @@ var Agent4 = class _Agent {
345574
345579
  }
345575
345580
  updateProviders(value) {
345576
345581
  const before = this.config.providers();
345577
- this.config.set("models", "providers", mergeProviderSecrets(value, before));
345582
+ const merged = mergeProviderSecrets(value, before);
345583
+ resetEditedModelValidationEvidence(merged, before);
345584
+ this.config.set("models", "providers", merged);
345578
345585
  const after = this.config.providers();
345579
345586
  const beforeById = new Map(before.map((provider) => [provider.id, provider]));
345580
345587
  const afterById = new Map(after.map((provider) => [provider.id, provider]));
@@ -347660,6 +347667,19 @@ Review this persisted peer result and summarize or continue the parent task as n
347660
347667
  this.writeStoredConversationState(stored, targetWs);
347661
347668
  return true;
347662
347669
  }
347670
+ reorderConversationContinuations(orderedIds) {
347671
+ const currentIds = this.continuations.filter((item) => item.queueMode === "followUp" && !!item.clientMessageId).map((item) => String(item.clientMessageId));
347672
+ const completeOrder = orderedIds.length === currentIds.length && new Set(orderedIds).size === orderedIds.length && orderedIds.every((id) => currentIds.includes(id));
347673
+ if (!completeOrder) throw new Error("A complete queue order with unique current item ids is required");
347674
+ const byId = new Map(this.continuations.flatMap((item) => item.queueMode === "followUp" && item.clientMessageId ? [[String(item.clientMessageId), item]] : []));
347675
+ let nextIndex = 0;
347676
+ this.continuations = this.continuations.map((item) => {
347677
+ if (item.queueMode !== "followUp" || !item.clientMessageId) return item;
347678
+ return byId.get(orderedIds[nextIndex++]);
347679
+ });
347680
+ this.saveWorkspaceConversationState(true);
347681
+ return this.conversationContinuations();
347682
+ }
347663
347683
  renameConversation(id, title, ws = this.workspace.current) {
347664
347684
  const targetWs = ws || this.workspace.current;
347665
347685
  if (!targetWs) return false;
@@ -350465,6 +350485,9 @@ ${msg.content}
350465
350485
  const fallbackEnabled = this.config.getBool("models", "fallback_on_unavailable");
350466
350486
  const observedFailure = classifyRouteFailure(errorText);
350467
350487
  const observedDeployment = this.activeDeployment();
350488
+ if (observedFailure.type === "balance_exhausted" && observedDeployment) {
350489
+ this.providerBalanceBlockedUntilByDeployment.set(deploymentIdentity(observedDeployment), Date.now() + 5 * 6e4);
350490
+ }
350468
350491
  const previousAttempt = observedDeployment && this.lastRouteDecision ? [...this.lastRouteDecision.attempts].reverse().find((attempt) => deploymentIdentity(attempt.deployment) === deploymentIdentity(observedDeployment)) : void 0;
350469
350492
  if (this.model === "auto" && this.routeAttemptStartedAt === 0 && (this.lastRouteDecision?.finalStatus === "failed" || this.lastRouteDecision?.finalStatus === "blocked") && previousAttempt?.status === "failed" && previousAttempt.errorType === observedFailure.type) {
350470
350493
  return null;
@@ -350515,14 +350538,12 @@ ${msg.content}
350515
350538
  return current2.modelId;
350516
350539
  }
350517
350540
  if (!fallbackEnabled) return null;
350518
- if (!observedFailure.retryable || !observedFailure.switchAllowed || this.routeStreamCommitted || this.routeSideEffectCommitted) return null;
350541
+ if (!observedFailure.switchAllowed || this.routeStreamCommitted || this.routeSideEffectCommitted) return null;
350519
350542
  const current = this.model;
350520
- const all = this.scopedSwitchModels(current).filter((m2) => m2.name !== current);
350543
+ const currentDeployment = observedDeployment;
350544
+ const all = this.scopedSwitchModels(current).filter((m2) => !currentDeployment || deploymentIdentity(this.deploymentRef(m2)) !== deploymentIdentity(currentDeployment));
350521
350545
  if (!all.length) return null;
350522
- const usable = all.filter((m2) => {
350523
- const status = String(m2.evaluation?.status || "unknown").toLowerCase();
350524
- return status !== "unavailable" && !status.startsWith("error");
350525
- });
350546
+ const usable = all.filter((m2) => !this.isBalanceBlockedDeployment(this.deploymentRef(m2)) && !modelConfigIsUnavailable(m2));
350526
350547
  if (!usable.length) return null;
350527
350548
  const pref = this.config.autoSwitchPreference();
350528
350549
  const ranked = [...usable].sort((a3, b2) => this.modelScore(b2, pref, false, false) - this.modelScore(a3, pref, false, false));
@@ -351198,7 +351219,7 @@ ${persisted.map((guide, index) => `Guide ${index + 1}: ${guide.text}`).join("\n"
351198
351219
  throw e3;
351199
351220
  }
351200
351221
  const msg = e3 instanceof Error ? e3.message : String(e3);
351201
- if (/\b402\b|insufficient balance|insufficient funds|payment required|余额不足/i.test(msg)) {
351222
+ if (/\b402\b|insufficient balance|insufficient funds|payment required|insufficient[_ -]?quota|quota (?:exceeded|exhausted)|credit(?:s| balance)? (?:exhausted|depleted)|billing hard limit|budget exhausted|余额不足|额度不足|配额(?:不足|耗尽|超限)/i.test(msg)) {
351202
351223
  this.noteProviderBalanceFailure();
351203
351224
  }
351204
351225
  this.status = "error";
@@ -353106,11 +353127,63 @@ function routeProviderFingerprint(provider) {
353106
353127
  enabled: provider.enabled,
353107
353128
  models: (provider.models || []).map((model) => ({
353108
353129
  name: model.name,
353130
+ display: model.display,
353131
+ description: model.description,
353132
+ maxTokens: model.max_tokens,
353133
+ vision: model.vision,
353134
+ thinking: !!model.thinking,
353135
+ imageOutput: !!model.image_output,
353109
353136
  enabled: model.enabled !== false,
353110
- logicalModelGroupId: model.logical_model_group_id || ""
353137
+ preview: !!model.preview,
353138
+ logicalModelGroupId: model.logical_model_group_id || "",
353139
+ privacy: model.privacy || [],
353140
+ capabilities: model.capabilities || [],
353141
+ supportedParameters: model.supported_parameters || [],
353142
+ routePreference: model.route_preference,
353143
+ fallbackOnly: !!model.fallback_only,
353144
+ thinkingTierMap: model.thinking_tier_map || {}
353111
353145
  }))
353112
353146
  });
353113
353147
  }
353148
+ function modelConfigurationFingerprint(model) {
353149
+ const { validation, evaluation, _previous_name, previous_name, ...configuration } = model;
353150
+ void validation;
353151
+ void evaluation;
353152
+ void _previous_name;
353153
+ void previous_name;
353154
+ return JSON.stringify(configuration);
353155
+ }
353156
+ function resetEditedModelValidationEvidence(incomingProviders, existingProviders) {
353157
+ const existingById = new Map(existingProviders.map((provider) => [provider.id, provider]));
353158
+ const existingByName = new Map(existingProviders.map((provider) => [provider.name, provider]));
353159
+ for (const rawProvider of incomingProviders) {
353160
+ if (!rawProvider || typeof rawProvider !== "object" || Array.isArray(rawProvider)) continue;
353161
+ const provider = rawProvider;
353162
+ const previousProvider = existingById.get(String(provider.id || "")) || existingByName.get(String(provider._previous_name || provider.previous_name || provider.name || ""));
353163
+ const models = Array.isArray(provider.models) ? provider.models : [];
353164
+ const providerConnectionChanged = !!previousProvider && (String(provider.base_url || provider.endpoint || "") !== previousProvider.base_url || String(provider.protocol || "") !== previousProvider.protocol);
353165
+ for (const rawModel of models) {
353166
+ if (!rawModel || typeof rawModel !== "object" || Array.isArray(rawModel)) continue;
353167
+ const model = rawModel;
353168
+ const previousName = String(model._previous_name || model.previous_name || model.name || "");
353169
+ const previousModel = previousProvider?.models.find((candidate) => candidate.name === previousName);
353170
+ const edited = providerConnectionChanged || !!previousModel && modelConfigurationFingerprint(model) !== modelConfigurationFingerprint(previousModel);
353171
+ delete model._previous_name;
353172
+ delete model.previous_name;
353173
+ if (!edited) continue;
353174
+ model.validation = { level: "discovered", status: "degraded", checked_at: "", capabilities: {} };
353175
+ delete model.evaluation;
353176
+ model.speed_rating = "unknown";
353177
+ model.capability_rating = "unknown";
353178
+ }
353179
+ }
353180
+ }
353181
+ function modelConfigIsUnavailable(model) {
353182
+ const validationStatus = effectiveModelValidationStatus(model);
353183
+ if (model.validation?.level !== "discovered" && (validationStatus === "unavailable" || validationStatus === "auth_error" || validationStatus === "invalid_config")) return true;
353184
+ const evaluationStatus = validationStatus === "degraded" ? "degraded" : String(model.evaluation?.status || "").toLowerCase();
353185
+ return evaluationStatus === "unavailable" || evaluationStatus.startsWith("error");
353186
+ }
353114
353187
  function parseDeploymentSelectionValue2(value) {
353115
353188
  const marker = String(value || "").trim();
353116
353189
  if (!marker.startsWith("deployment:")) return null;
@@ -353127,9 +353200,9 @@ function parseDeploymentSelectionValue2(value) {
353127
353200
  function effectiveModelValidationStatus(model) {
353128
353201
  const raw = String(model.validation?.status || "").toLowerCase();
353129
353202
  if (raw === "auth_error") return raw;
353203
+ if (String(model.validation?.level || "").toLowerCase() === "discovered") return "degraded";
353130
353204
  const textEvidence = model.validation?.capabilities?.text === true || model.validation?.capabilities?.text_input === true || model.validation?.capabilities?.text_output === true || model.evaluation?.text_input === true || model.evaluation?.text_output === true;
353131
353205
  if (textEvidence && raw === "unavailable") return "degraded";
353132
- if (!raw && String(model.validation?.level || "").toLowerCase() === "discovered") return "degraded";
353133
353206
  return ["verified", "degraded", "unavailable", "auth_error", "rate_limited", "invalid_config"].includes(raw) ? raw : "unavailable";
353134
353207
  }
353135
353208
  function routeToolIsReadOnly(name50, rawArgs) {
@@ -353336,6 +353409,33 @@ ${text}`;
353336
353409
  this.emitQueueUpdate(runtime);
353337
353410
  return true;
353338
353411
  }
353412
+ reorderQueueItems(target, orderedIdsInput) {
353413
+ const runtime = this.findRuntime(target);
353414
+ if (!runtime) throw new Error("Target conversation runtime is unavailable");
353415
+ const currentItems = this.queueItems(runtime.target);
353416
+ const orderedIds = Array.isArray(orderedIdsInput) ? orderedIdsInput.map((id) => String(id || "").trim()) : [];
353417
+ const currentIds = currentItems.map((item) => item.id);
353418
+ const completeOrder = orderedIds.length === currentIds.length && new Set(orderedIds).size === orderedIds.length && orderedIds.every((id) => currentIds.includes(id));
353419
+ if (!completeOrder) throw new Error("A complete queue order with unique current item ids is required");
353420
+ const persistedIds = runtime.runner.conversationContinuations().filter((item) => item.queueMode === "followUp" && !!item.clientMessageId).map((item) => String(item.clientMessageId));
353421
+ if (persistedIds.length !== currentIds.length || new Set(persistedIds).size !== persistedIds.length || persistedIds.some((id) => !currentIds.includes(id))) {
353422
+ throw new Error("Persisted queue does not match the complete queue order");
353423
+ }
353424
+ const pendingById = new Map(runtime.pendingNextTurn.flatMap((item) => {
353425
+ if (item.queueMode !== "followUp" || typeof item.message === "string" || !item.message.clientMessageId) return [];
353426
+ return [[String(item.message.clientMessageId), item]];
353427
+ }));
353428
+ const reorderedPending = orderedIds.map((id) => pendingById.get(id));
353429
+ let nextIndex = 0;
353430
+ runtime.pendingNextTurn = runtime.pendingNextTurn.map((item) => {
353431
+ if (item.queueMode !== "followUp" || typeof item.message === "string" || !item.message.clientMessageId) return item;
353432
+ return reorderedPending[nextIndex++];
353433
+ });
353434
+ runtime.runner.reorderConversationContinuations(orderedIds);
353435
+ runtime.queued.followUp = orderedIds.map((id) => pendingById.get(id)).map((item) => typeof item.message === "string" ? item.message : item.message.text);
353436
+ this.emitQueueUpdate(runtime);
353437
+ return this.queueItems(runtime.target);
353438
+ }
353339
353439
  setQueuePaused(target, paused) {
353340
353440
  const runtime = this.findRuntime(target);
353341
353441
  if (!runtime) throw new Error("Target conversation runtime is unavailable");
@@ -353362,6 +353462,8 @@ ${text}`;
353362
353462
  this.updateQueueItem(runtime.target, String(input2.id || ""), String(input2.text || ""));
353363
353463
  } else if (action === "delete") {
353364
353464
  if (!this.deleteQueueItem(runtime.target, String(input2.id || ""))) throw new Error("Queue item was not found");
353465
+ } else if (action === "reorder") {
353466
+ this.reorderQueueItems(runtime.target, input2.orderedIds || []);
353365
353467
  } else if (action === "toggle_pause") {
353366
353468
  this.setQueuePaused(runtime.target, !runtime.queuePaused);
353367
353469
  } else if (action === "guide") {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "newmark-agent",
3
3
  "productName": "Newmark Agent",
4
- "version": "0.4.8",
4
+ "version": "0.4.9",
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": {
@@ -53,7 +53,7 @@
53
53
  "test:desktop": "npm run build && npm run test:desktop:built",
54
54
  "test:deletion-safety": "npm run build && npm run test:deletion-safety:built",
55
55
  "test:deletion-safety:built": "node scripts/deletion-safety-stress.cjs",
56
- "test:desktop:built": "node dist/tests/verify.js && node dist/tests/thinkingTierMapCacheStressVerify.js && node dist/tests/computerUseSessionVerify.js && node dist/tests/contextSystemV2Verify.js && node dist/tests/contextSystemV2StressVerify.js && node dist/tests/providerAdapterV2Verify.js && node dist/tests/providerTimeoutRecoveryVerify.js && node dist/tests/agentRuntimeV2Verify.js && node dist/tests/toolchainExposureV2Verify.js && node dist/tests/localOcrFallbackVerify.js && node dist/tests/dev018ModeSubagentStressVerify.js && node dist/tests/conversationBranchStressVerify.js && node dist/tests/conversationArchiveConcurrencyVerify.js && node dist/tests/conversationArchiveRuntimeVerify.js && node dist/tests/dev040ComprehensiveStressVerify.js && node dist/tests/memoryPolicyVerify.js && node dist/tests/newmarkSelectVerify.js && node dist/tests/mcpManagerVerify.js && node dist/tests/dshCompatibilityVerify.js && node dist/tests/performanceOptimizationVerify.js && node scripts/compression-pressure-stress.cjs && node dist/tests/compressionFidelityVerify.js && node dist/tests/responseTrajectoryVerify.js && node dist/tests/normalChatRegressionVerify.js && node dist/tests/dev008-subagent.js && node dist/tests/dev009Verify.js && node dist/tests/runtimeIsolationVerify.js && node dist/tests/runtimePoolCapacityVerify.js && node dist/tests/guideWorkRunVerify.js && node dist/tests/modelSwitchBehaviorVerify.js && node scripts/flow-pause-stop-draft-stress.cjs && node dist/tests/guideUiReconcileVerify.js && node dist/tests/queueAttachmentIsolationVerify.js && node dist/tests/workspaceMenuVerify.js && node dist/tests/userImagePersistenceVerify.js && node dist/tests/displayImageVerify.js && node dist/tests/visualPreferencesVerify.js && node dist/tests/browserUseVerify.js && node dist/tests/toolProcessVerify.js && node dist/tests/toolProvisioningVerify.js && node dist/tests/taskToolsVerify.js && node dist/tests/contextCacheHitStressVerify.js && node dist/tests/startupPrewarmVerify.js && node dist/tests/pdfPreviewServerVerify.js && node dist/tests/editorLifecycleVerify.js && node dist/tests/terminalTakeoverVerify.js && node dist/tests/workspaceFileRouterVerify.js && node dist/tests/screenCaptureIndependentVerify.js && node dist/tests/computerUsePerformanceVerify.js && node dist/tests/autoRouterVerify.js && node dist/tests/autoAgentIntegrationVerify.js && node dist/tests/autoRouteRatingVerify.js && node dist/tests/providerIdentityVerify.js && node dist/tests/modelValidationVerify.js && node dist/tests/modelValidationAgentIntegrationVerify.js && node scripts/deletion-safety-stress.cjs",
56
+ "test:desktop:built": "node dist/tests/verify.js && node dist/tests/thinkingTierMapCacheStressVerify.js && node dist/tests/computerUseSessionVerify.js && node dist/tests/contextSystemV2Verify.js && node dist/tests/contextSystemV2StressVerify.js && node dist/tests/providerAdapterV2Verify.js && node dist/tests/providerTimeoutRecoveryVerify.js && node dist/tests/agentRuntimeV2Verify.js && node dist/tests/toolchainExposureV2Verify.js && node dist/tests/localOcrFallbackVerify.js && node dist/tests/dev018ModeSubagentStressVerify.js && node dist/tests/conversationBranchStressVerify.js && node dist/tests/conversationArchiveConcurrencyVerify.js && node dist/tests/conversationArchiveRuntimeVerify.js && node dist/tests/dev040ComprehensiveStressVerify.js && node dist/tests/memoryPolicyVerify.js && node dist/tests/newmarkSelectVerify.js && node dist/tests/mcpManagerVerify.js && node dist/tests/dshCompatibilityVerify.js && node dist/tests/performanceOptimizationVerify.js && node scripts/compression-pressure-stress.cjs && node dist/tests/compressionFidelityVerify.js && node dist/tests/responseTrajectoryVerify.js && node dist/tests/normalChatRegressionVerify.js && node dist/tests/dev008-subagent.js && node dist/tests/dev009Verify.js && node dist/tests/runtimeIsolationVerify.js && node dist/tests/runtimePoolCapacityVerify.js && node dist/tests/guideWorkRunVerify.js && node dist/tests/modelSwitchBehaviorVerify.js && node scripts/flow-pause-stop-draft-stress.cjs && node dist/tests/guideUiReconcileVerify.js && node dist/tests/queueAttachmentIsolationVerify.js && node dist/tests/workspaceMenuVerify.js && node dist/tests/userImagePersistenceVerify.js && node dist/tests/displayImageVerify.js && node dist/tests/visualPreferencesVerify.js && node dist/tests/browserUseVerify.js && node dist/tests/toolProcessVerify.js && node dist/tests/toolProvisioningVerify.js && node dist/tests/taskToolsVerify.js && node dist/tests/contextCacheHitStressVerify.js && node dist/tests/startupPrewarmVerify.js && node dist/tests/pdfPreviewServerVerify.js && node dist/tests/editorLifecycleVerify.js && node dist/tests/terminalTakeoverVerify.js && node dist/tests/workspaceFileRouterVerify.js && node dist/tests/screenCaptureIndependentVerify.js && node dist/tests/computerUsePerformanceVerify.js && node dist/tests/autoRouterVerify.js && node dist/tests/autoAgentIntegrationVerify.js && node dist/tests/modelRecoveryStressVerify.js && node dist/tests/autoRouteRatingVerify.js && node dist/tests/providerIdentityVerify.js && node dist/tests/modelValidationVerify.js && node dist/tests/modelValidationAgentIntegrationVerify.js && node scripts/deletion-safety-stress.cjs",
57
57
  "test:conversation-branch-stress": "npm run build && node dist/tests/conversationBranchStressVerify.js",
58
58
  "test:conversation-archive-concurrency": "npm run build && node dist/tests/conversationArchiveConcurrencyVerify.js",
59
59
  "test:memory-policy": "npm run build && node dist/tests/memoryPolicyVerify.js",
@@ -85,6 +85,8 @@
85
85
  "test:dev009": "npm run build && node dist/tests/dev009Verify.js && node dist/tests/runtimeIsolationVerify.js && node dist/tests/guideWorkRunVerify.js && node dist/tests/guideUiReconcileVerify.js && node dist/tests/queueAttachmentIsolationVerify.js && node dist/tests/workspaceMenuVerify.js && node dist/tests/userImagePersistenceVerify.js && node dist/tests/visualPreferencesVerify.js && node dist/tests/browserUseVerify.js && node dist/tests/toolProcessVerify.js && node dist/tests/startupPrewarmVerify.js && node dist/tests/pdfPreviewServerVerify.js && node dist/tests/editorLifecycleVerify.js && node dist/tests/computerUsePerformanceVerify.js && electron dist/tests/browserUseElectronVerify.js",
86
86
  "test:dev008": "npm run build && node dist/tests/dev008-subagent.js",
87
87
  "test:auto-router": "npm run build && node dist/tests/autoRouterVerify.js && node dist/tests/autoAgentIntegrationVerify.js && node dist/tests/autoRouteRatingVerify.js && node dist/tests/providerIdentityVerify.js",
88
+ "test:model-recovery-stress": "npm run build && node dist/tests/modelRecoveryStressVerify.js",
89
+ "test:remote-touch-status": "npm run build && node dist/tests/remoteTouchServerStatusVerify.js",
88
90
  "test:model-validation": "npm run build && node dist/tests/modelValidationVerify.js && node dist/tests/modelValidationAgentIntegrationVerify.js && node dist/tests/intelligenceTierVerify.js",
89
91
  "test:runtime-pool": "npm run build && node dist/tests/runtimePoolCapacityVerify.js",
90
92
  "test:cli-tools": "npm run build && node dist/tests/cliToolContractVerify.js && node dist/tests/openAIHubAnthropicSmokeContractVerify.js && node dist/tests/cliComputerUseAccuracyVerify.js",
@@ -104,6 +106,7 @@
104
106
  "release:safe-blackbox-gates": "node scripts/release-safe-blackbox-gates.cjs",
105
107
  "release:gui-no-model-smoke": "node scripts/release-gui-no-model-smoke.cjs",
106
108
  "release:safe-shared-root-restart-stress": "node scripts/release-safe-shared-root-restart-stress.cjs",
109
+ "release:pc-gui-tui-remote-service-stress": "node scripts/release-pc-gui-tui-remote-service-stress.cjs",
107
110
  "release:111-cli-smoke": "node scripts/release-111-cli-smoke.cjs",
108
111
  "release:111-ui-smoke": "node scripts/release-111-ui-smoke.cjs",
109
112
  "release:computer-use-vision-smoke": "node scripts/release-computer-use-vision-smoke.cjs",