ur-agent 1.45.4 → 1.45.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.45.6
4
+
5
+ - Deduplicated project verification approval so compile/test/lint commands are
6
+ offered at most once per user turn. The approval marker is cleared for the
7
+ next user task, preserving one explicit decision per task.
8
+ - Kept AutoApprove behavior, test execution policy, and explicit publishing
9
+ boundaries unchanged. Added regression coverage and synchronized user,
10
+ technical, static-site, npm, IDE, and bundled release metadata.
11
+
12
+ ## 1.45.5
13
+
14
+ - Bounded Ollama Cloud response-header and streaming phases to 120 seconds by
15
+ default while preserving the five-minute allowance for local Ollama models.
16
+ `API_TIMEOUT_MS` and per-request timeouts still take precedence.
17
+ - Stopped deliberate Ollama Cloud stream deadlines from triggering the shared
18
+ non-streaming fallback and retry chain. Other providers and local Ollama
19
+ retain their existing fallback and retry behavior.
20
+ - Extended the deterministic verifier to reject turns that end by promising an
21
+ immediate file change or command but emit no successful matching tool call.
22
+ Conditional plans and instructional prose remain unaffected.
23
+ - Added focused timeout, retry-containment, intent-detection, and verifier
24
+ integration coverage; synchronized npm, IDE extension, static-site, user,
25
+ validation, and technical release metadata.
26
+
3
27
  ## 1.45.4
4
28
 
5
29
  - Added mandatory provider-first model selection for the first interactive run
package/README.md CHANGED
@@ -636,8 +636,9 @@ the permission boundary matters.
636
636
  otherwise pause for permission approval, while user-input dialogs still ask.
637
637
  - `--dangerously-skip-permissions` should only be used inside disposable
638
638
  sandboxes.
639
- - The verifier checks for false completion claims, repeated tool-call loops,
640
- empty assistant turns, and project gates.
639
+ - The verifier checks for false completion claims, immediate-action promises
640
+ that end without the matching tool call, repeated tool-call loops, empty
641
+ assistant turns, and project gates.
641
642
  - Project gates can be configured in `.ur/verify.json`.
642
643
  - `ur test-first install` writes detected compile/test/lint commands into
643
644
  `.ur/verify.json` so mutating turns have command evidence before completion.
package/dist/cli.js CHANGED
@@ -56931,6 +56931,7 @@ var init_kimiToolCalls = __esm(() => {
56931
56931
  var exports_ollama = {};
56932
56932
  __export(exports_ollama, {
56933
56933
  mergeToolCalls: () => mergeToolCalls,
56934
+ isOllamaCloudModel: () => isOllamaCloudModel2,
56934
56935
  getOllamaRequestTimeoutMs: () => getOllamaRequestTimeoutMs,
56935
56936
  getEffectiveOllamaBaseUrl: () => getEffectiveOllamaBaseUrl,
56936
56937
  createOllamaURHQClient: () => createOllamaURHQClient
@@ -56986,7 +56987,7 @@ async function createNonStreamingRequest(params, options) {
56986
56987
  return ollamaResponseToURHQMessage(json2, params);
56987
56988
  }
56988
56989
  async function fetchOllamaChat(params, stream4, controller, options) {
56989
- const timeout = getOllamaRequestTimeoutMs(options);
56990
+ const timeout = getOllamaRequestTimeoutMs(options, process.env, params.model);
56990
56991
  const timeoutId = timeout > 0 ? setTimeout(() => controller.abort(), timeout) : undefined;
56991
56992
  try {
56992
56993
  const capabilities = await getOllamaModelCapabilities(params.model, controller.signal);
@@ -57064,7 +57065,7 @@ function createLinkedAbortController(options) {
57064
57065
  signal.addEventListener("abort", () => controller.abort(), { once: true });
57065
57066
  return controller;
57066
57067
  }
57067
- function getOllamaRequestTimeoutMs(options, env4 = process.env) {
57068
+ function getOllamaRequestTimeoutMs(options, env4 = process.env, model) {
57068
57069
  if (options?.timeoutMs !== undefined || options?.timeout !== undefined) {
57069
57070
  return options.timeoutMs ?? options.timeout ?? DEFAULT_OLLAMA_REQUEST_TIMEOUT_MS;
57070
57071
  }
@@ -57072,7 +57073,16 @@ function getOllamaRequestTimeoutMs(options, env4 = process.env) {
57072
57073
  if (override > 0) {
57073
57074
  return override;
57074
57075
  }
57075
- return isTruthyEnv(env4.UR_CODE_REMOTE) ? REMOTE_OLLAMA_REQUEST_TIMEOUT_MS : DEFAULT_OLLAMA_REQUEST_TIMEOUT_MS;
57076
+ if (isTruthyEnv(env4.UR_CODE_REMOTE)) {
57077
+ return REMOTE_OLLAMA_REQUEST_TIMEOUT_MS;
57078
+ }
57079
+ if (isOllamaCloudModel2(model)) {
57080
+ return CLOUD_OLLAMA_REQUEST_TIMEOUT_MS;
57081
+ }
57082
+ return DEFAULT_OLLAMA_REQUEST_TIMEOUT_MS;
57083
+ }
57084
+ function isOllamaCloudModel2(model) {
57085
+ return model?.trim().toLowerCase().endsWith(":cloud") ?? false;
57076
57086
  }
57077
57087
  function isTruthyEnv(value) {
57078
57088
  if (!value) {
@@ -57473,7 +57483,7 @@ async function* streamURHQEvents(response, params, controller, requestId, option
57473
57483
  }
57474
57484
  return events;
57475
57485
  };
57476
- for await (const chunk of readOllamaChunks(response, controller, getOllamaRequestTimeoutMs(options), options)) {
57486
+ for await (const chunk of readOllamaChunks(response, controller, getOllamaRequestTimeoutMs(options, process.env, params.model), options)) {
57477
57487
  if (chunk.error) {
57478
57488
  throw new Error(chunk.error);
57479
57489
  }
@@ -57920,7 +57930,7 @@ function parseToolInput(input) {
57920
57930
  }
57921
57931
  return parsed ?? {};
57922
57932
  }
57923
- var DEFAULT_OLLAMA_REQUEST_TIMEOUT_MS = 300000, REMOTE_OLLAMA_REQUEST_TIMEOUT_MS = 120000, OLLAMA_GATEWAY_TIMEOUT_MESSAGE = "Ollama gateway timed out while waiting for the model to respond. Check the selected Ollama endpoint or increase API_TIMEOUT_MS if the model needs more time.", ollamaModelCapabilitiesCache, ollamaBaseUrlOverride, warnedToolsUnsupportedModels, TEXT_TOOL_CALL_HINT;
57933
+ var DEFAULT_OLLAMA_REQUEST_TIMEOUT_MS = 300000, REMOTE_OLLAMA_REQUEST_TIMEOUT_MS = 120000, CLOUD_OLLAMA_REQUEST_TIMEOUT_MS = 120000, OLLAMA_GATEWAY_TIMEOUT_MESSAGE = "Ollama gateway timed out while waiting for the model to respond. Check the selected Ollama endpoint or increase API_TIMEOUT_MS if the model needs more time.", ollamaModelCapabilitiesCache, ollamaBaseUrlOverride, warnedToolsUnsupportedModels, TEXT_TOOL_CALL_HINT;
57924
57934
  var init_ollama = __esm(() => {
57925
57935
  init_urhq_sdk();
57926
57936
  init_ollamaModels();
@@ -73087,7 +73097,7 @@ var init_auth = __esm(() => {
73087
73097
 
73088
73098
  // src/utils/userAgent.ts
73089
73099
  function getURCodeUserAgent() {
73090
- return `ur/${"1.45.4"}`;
73100
+ return `ur/${"1.45.6"}`;
73091
73101
  }
73092
73102
 
73093
73103
  // src/utils/workloadContext.ts
@@ -73109,7 +73119,7 @@ function getUserAgent() {
73109
73119
  const clientApp = process.env.UR_AGENT_SDK_CLIENT_APP ? `, client-app/${process.env.UR_AGENT_SDK_CLIENT_APP}` : "";
73110
73120
  const workload = getWorkload();
73111
73121
  const workloadSuffix = workload ? `, workload/${workload}` : "";
73112
- return `ur-cli/${"1.45.4"} (${process.env.USER_TYPE}, ${process.env.UR_CODE_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
73122
+ return `ur-cli/${"1.45.6"} (${process.env.USER_TYPE}, ${process.env.UR_CODE_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
73113
73123
  }
73114
73124
  function getMCPUserAgent() {
73115
73125
  const parts = [];
@@ -73123,7 +73133,7 @@ function getMCPUserAgent() {
73123
73133
  parts.push(`client-app/${process.env.UR_AGENT_SDK_CLIENT_APP}`);
73124
73134
  }
73125
73135
  const suffix = parts.length > 0 ? ` (${parts.join(", ")})` : "";
73126
- return `ur/${"1.45.4"}${suffix}`;
73136
+ return `ur/${"1.45.6"}${suffix}`;
73127
73137
  }
73128
73138
  function getWebFetchUserAgent() {
73129
73139
  return `UR-User (${getURCodeUserAgent()})`;
@@ -73261,7 +73271,7 @@ var init_user = __esm(() => {
73261
73271
  deviceId,
73262
73272
  sessionId: getSessionId(),
73263
73273
  email: getEmail(),
73264
- appVersion: "1.45.4",
73274
+ appVersion: "1.45.6",
73265
73275
  platform: getHostPlatformForAnalytics(),
73266
73276
  organizationUuid,
73267
73277
  accountUuid,
@@ -79836,7 +79846,7 @@ var init_metadata = __esm(() => {
79836
79846
  COMPOUND_OPERATOR_REGEX = /\s*(?:&&|\|\||[;|])\s*/;
79837
79847
  WHITESPACE_REGEX = /\s+/;
79838
79848
  getVersionBase = memoize_default(() => {
79839
- const match = "1.45.4".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
79849
+ const match = "1.45.6".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
79840
79850
  return match ? match[0] : undefined;
79841
79851
  });
79842
79852
  buildEnvContext = memoize_default(async () => {
@@ -79876,7 +79886,7 @@ var init_metadata = __esm(() => {
79876
79886
  isGithubAction: isEnvTruthy(process.env.GITHUB_ACTIONS),
79877
79887
  isURCodeAction: isEnvTruthy(process.env.UR_CODE_ACTION),
79878
79888
  isURAiAuth: isURAISubscriber(),
79879
- version: "1.45.4",
79889
+ version: "1.45.6",
79880
79890
  versionBase: getVersionBase(),
79881
79891
  buildTime: "",
79882
79892
  deploymentEnvironment: env2.detectDeploymentEnvironment(),
@@ -80546,7 +80556,7 @@ function initialize1PEventLogging() {
80546
80556
  const platform2 = getPlatform();
80547
80557
  const attributes = {
80548
80558
  [import_semantic_conventions4.ATTR_SERVICE_NAME]: "ur",
80549
- [import_semantic_conventions4.ATTR_SERVICE_VERSION]: "1.45.4"
80559
+ [import_semantic_conventions4.ATTR_SERVICE_VERSION]: "1.45.6"
80550
80560
  };
80551
80561
  if (platform2 === "wsl") {
80552
80562
  const wslVersion = getWslVersion();
@@ -80573,7 +80583,7 @@ function initialize1PEventLogging() {
80573
80583
  })
80574
80584
  ]
80575
80585
  });
80576
- firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("com.urhq.ur.events", "1.45.4");
80586
+ firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("com.urhq.ur.events", "1.45.6");
80577
80587
  }
80578
80588
  async function reinitialize1PEventLoggingIfConfigChanged() {
80579
80589
  if (!is1PEventLoggingEnabled() || !firstPartyEventLoggerProvider) {
@@ -86498,7 +86508,7 @@ function formatAgentTrendReport(report = buildAgentTrendReport()) {
86498
86508
  function formatA2AAgentCard(options = {}, pretty = true) {
86499
86509
  return JSON.stringify(buildA2AAgentCard(options), null, pretty ? 2 : 0);
86500
86510
  }
86501
- var urVersion = "1.45.4", coverage, priorityRoadmap;
86511
+ var urVersion = "1.45.6", coverage, priorityRoadmap;
86502
86512
  var init_trends = __esm(() => {
86503
86513
  coverage = [
86504
86514
  {
@@ -88364,7 +88374,7 @@ function getAttributionHeader(fingerprint) {
88364
88374
  if (!isAttributionHeaderEnabled()) {
88365
88375
  return "";
88366
88376
  }
88367
- const version2 = `${"1.45.4"}.${fingerprint}`;
88377
+ const version2 = `${"1.45.6"}.${fingerprint}`;
88368
88378
  const entrypoint = process.env.UR_CODE_ENTRYPOINT ?? "unknown";
88369
88379
  const cch = "";
88370
88380
  const workload = getWorkload();
@@ -146550,6 +146560,25 @@ var init_projectQuality = __esm(() => {
146550
146560
  });
146551
146561
 
146552
146562
  // src/services/verifier/doneDetector.ts
146563
+ function detectImmediateIntent(text) {
146564
+ const tail = text.trim().slice(-600);
146565
+ const clauses = tail.split(/(?:\n+|(?<=[.!?])\s+)/).map((clause2) => clause2.trim()).filter(Boolean);
146566
+ const clause = clauses.at(-1) ?? "";
146567
+ if (!clause || /^(?:if|when|once|after|before)\b/i.test(clause) || /\b(?:if|when|once|after|unless|until)\b.+$/i.test(clause)) {
146568
+ return null;
146569
+ }
146570
+ const lead = "(?:now[, :]*)?(?:let me|i(?:'ll| will| am going to|'m going to))";
146571
+ if (new RegExp(`\\b${lead}\\s+(?:now\\s+)?${WRITE_INTENT_VERBS}\\b`, "i").test(clause)) {
146572
+ return "write_intent";
146573
+ }
146574
+ if (new RegExp(`\\b${lead}\\s+(?:now\\s+)?${RUN_INTENT_VERBS}\\b`, "i").test(clause)) {
146575
+ return "run_intent";
146576
+ }
146577
+ if (new RegExp(`^${WRITE_INTENT_GERUNDS}\\b.*\\bnow[.!]?$`, "i").test(clause)) {
146578
+ return "write_intent";
146579
+ }
146580
+ return null;
146581
+ }
146553
146582
  function detectDoneClaim(text) {
146554
146583
  if (!text)
146555
146584
  return null;
@@ -146569,7 +146598,7 @@ function detectDoneClaim(text) {
146569
146598
  if (pattern.test(text))
146570
146599
  return "generic_done";
146571
146600
  }
146572
- return null;
146601
+ return detectImmediateIntent(text);
146573
146602
  }
146574
146603
  function evaluateDoneGate(claim, hasMutatingEffect, ranBash) {
146575
146604
  if (claim === "write_claim" || claim === "edit_claim" || claim === "delete_claim") {
@@ -146582,6 +146611,16 @@ function evaluateDoneGate(claim, hasMutatingEffect, ranBash) {
146582
146611
  reminder: "You claimed to have created, edited, or deleted files this turn but no Write / Edit / NotebookEdit / Bash tool call returned successfully. Make the actual tool call now, or correct the statement before continuing."
146583
146612
  };
146584
146613
  }
146614
+ if (claim === "write_intent") {
146615
+ if (hasMutatingEffect)
146616
+ return { ok: true };
146617
+ return {
146618
+ ok: false,
146619
+ claim,
146620
+ reason: "promised file action ended without a mutating tool call",
146621
+ reminder: "You ended by saying you were about to create, edit, or fix files, but no Write / Edit / NotebookEdit / Bash tool call returned successfully. Make the actual tool call now, or explain why you cannot continue."
146622
+ };
146623
+ }
146585
146624
  if (claim === "run_claim") {
146586
146625
  if (ranBash)
146587
146626
  return { ok: true };
@@ -146592,6 +146631,16 @@ function evaluateDoneGate(claim, hasMutatingEffect, ranBash) {
146592
146631
  reminder: "You claimed to have run a command this turn but no Bash tool call returned successfully. Run the command now or correct the statement."
146593
146632
  };
146594
146633
  }
146634
+ if (claim === "run_intent") {
146635
+ if (ranBash)
146636
+ return { ok: true };
146637
+ return {
146638
+ ok: false,
146639
+ claim,
146640
+ reason: "promised command ended without a successful Bash call",
146641
+ reminder: "You ended by saying you were about to run a command, but no Bash tool call returned successfully. Run the command now, or explain why you cannot continue."
146642
+ };
146643
+ }
146595
146644
  if (hasMutatingEffect || ranBash)
146596
146645
  return { ok: true };
146597
146646
  return {
@@ -146601,7 +146650,7 @@ function evaluateDoneGate(claim, hasMutatingEffect, ranBash) {
146601
146650
  reminder: "You declared the task complete but this turn made no Write / Edit / Bash / NotebookEdit tool call. If the task required no edits, say so explicitly. Otherwise, make the tool call now."
146602
146651
  };
146603
146652
  }
146604
- var DONE_PATTERNS;
146653
+ var DONE_PATTERNS, WRITE_INTENT_VERBS = "(?:create|write|edit|update|change|modify|patch|fix|remove|delete|rewrite|implement)", RUN_INTENT_VERBS = "(?:run|execute|test|build)", WRITE_INTENT_GERUNDS = "(?:creating|writing|editing|updating|changing|modifying|patching|fixing|removing|deleting|rewriting|implementing)";
146605
146654
  var init_doneDetector = __esm(() => {
146606
146655
  DONE_PATTERNS = [
146607
146656
  /\b(?:i|i've|i have)\s+(?:created|added|written|wrote|made)\b/i,
@@ -147068,11 +147117,13 @@ class Verifier {
147068
147117
  pluginValidatorsPromise;
147069
147118
  rejectionsByTurn = new Map;
147070
147119
  nudgedTurns = new Set;
147120
+ gateApprovalRequestedTurns = new Set;
147071
147121
  userTaskHintByTurn = new Map;
147072
147122
  maxRejections;
147073
147123
  cwd;
147074
147124
  enableSubagentNudge;
147075
147125
  mode;
147126
+ askBeforeGatesOverride;
147076
147127
  constructor(options2) {
147077
147128
  this.cwd = options2.cwd;
147078
147129
  this.maxRejections = options2.maxRejectionsPerTurn ?? DEFAULT_MAX_REJECTIONS_PER_TURN;
@@ -147080,6 +147131,7 @@ class Verifier {
147080
147131
  this.configPromise = loadVerifyConfig(options2.cwd);
147081
147132
  this.pluginValidatorsPromise = loadPluginValidators();
147082
147133
  this.mode = resolveMode(options2.mode);
147134
+ this.askBeforeGatesOverride = options2.askBeforeGates;
147083
147135
  const subagentEnabledByDefault = this.mode !== "off" && process.env.UR_VERIFIER_DISABLE_SUBAGENT !== "1" && isEnvTruthy(process.env.UR_VERIFIER_AUTO_SUBAGENT);
147084
147136
  this.enableSubagentNudge = options2.enableSubagentNudge ?? subagentEnabledByDefault;
147085
147137
  }
@@ -147087,6 +147139,7 @@ class Verifier {
147087
147139
  this.loops.reset();
147088
147140
  this.rejectionsByTurn.delete(turnId);
147089
147141
  this.nudgedTurns.delete(turnId);
147142
+ this.gateApprovalRequestedTurns.delete(turnId);
147090
147143
  if (userTaskHint)
147091
147144
  this.userTaskHintByTurn.set(turnId, userTaskHint);
147092
147145
  }
@@ -147129,14 +147182,16 @@ class Verifier {
147129
147182
  autoDetected = true;
147130
147183
  }
147131
147184
  if (commands && commands.length > 0) {
147132
- if (!askBeforeGatesEnabled() && getIsNonInteractiveSession()) {
147185
+ const shouldAskBeforeGates = this.askBeforeGatesOverride ?? (askBeforeGatesEnabled() || !getIsNonInteractiveSession());
147186
+ if (!shouldAskBeforeGates) {
147133
147187
  const result = await runGateCommands(commands, this.cwd, timeoutMs);
147134
147188
  if (!result.ok) {
147135
147189
  this.bumpRejection(turnId);
147136
147190
  const failed = result;
147137
147191
  return { ok: false, reminder: failed.reminder };
147138
147192
  }
147139
- } else {
147193
+ } else if (!this.gateApprovalRequestedTurns.has(turnId)) {
147194
+ this.gateApprovalRequestedTurns.add(turnId);
147140
147195
  this.bumpRejection(turnId);
147141
147196
  return {
147142
147197
  ok: false,
@@ -147185,6 +147240,7 @@ class Verifier {
147185
147240
  this.ledger.forget(turnId);
147186
147241
  this.rejectionsByTurn.delete(turnId);
147187
147242
  this.nudgedTurns.delete(turnId);
147243
+ this.gateApprovalRequestedTurns.delete(turnId);
147188
147244
  this.userTaskHintByTurn.delete(turnId);
147189
147245
  }
147190
147246
  bumpRejection(turnId) {
@@ -196545,7 +196601,7 @@ function getTelemetryAttributes() {
196545
196601
  attributes["session.id"] = sessionId;
196546
196602
  }
196547
196603
  if (shouldIncludeAttribute("OTEL_METRICS_INCLUDE_VERSION")) {
196548
- attributes["app.version"] = "1.45.4";
196604
+ attributes["app.version"] = "1.45.6";
196549
196605
  }
196550
196606
  const oauthAccount = getOauthAccountInfo();
196551
196607
  if (oauthAccount) {
@@ -232026,7 +232082,7 @@ function getInstallationEnv() {
232026
232082
  return;
232027
232083
  }
232028
232084
  function getURCodeVersion() {
232029
- return "1.45.4";
232085
+ return "1.45.6";
232030
232086
  }
232031
232087
  async function getInstalledVSCodeExtensionVersion(command) {
232032
232088
  const { stdout } = await execFileNoThrow(command, ["--list-extensions", "--show-versions"], {
@@ -239408,7 +239464,7 @@ async function setupSdkMcpClients(sdkMcpConfigs, sendMcpMessage) {
239408
239464
  const client2 = new Client({
239409
239465
  name: "ur",
239410
239466
  title: "UR",
239411
- version: "1.45.4",
239467
+ version: "1.45.6",
239412
239468
  description: "UR-Nexus autonomous engineering workflow engine",
239413
239469
  websiteUrl: PRODUCT_URL
239414
239470
  }, {
@@ -239771,7 +239827,7 @@ var init_client5 = __esm(() => {
239771
239827
  const client2 = new Client({
239772
239828
  name: "ur",
239773
239829
  title: "UR",
239774
- version: "1.45.4",
239830
+ version: "1.45.6",
239775
239831
  description: "UR-Nexus autonomous engineering workflow engine",
239776
239832
  websiteUrl: PRODUCT_URL
239777
239833
  }, {
@@ -246808,9 +246864,9 @@ async function assertMinVersion() {
246808
246864
  if (false) {}
246809
246865
  try {
246810
246866
  const versionConfig = await getDynamicConfig_BLOCKS_ON_INIT("tengu_version_config", { minVersion: "0.0.0" });
246811
- if (versionConfig.minVersion && lt("1.45.4", versionConfig.minVersion)) {
246867
+ if (versionConfig.minVersion && lt("1.45.6", versionConfig.minVersion)) {
246812
246868
  console.error(`
246813
- It looks like your version of UR (${"1.45.4"}) needs an update.
246869
+ It looks like your version of UR (${"1.45.6"}) needs an update.
246814
246870
  A newer version (${versionConfig.minVersion} or higher) is required to continue.
246815
246871
 
246816
246872
  To update, please run:
@@ -247026,7 +247082,7 @@ async function installGlobalPackage(specificVersion) {
247026
247082
  logError2(new AutoUpdaterError("Another process is currently installing an update"));
247027
247083
  logEvent("tengu_auto_updater_lock_contention", {
247028
247084
  pid: process.pid,
247029
- currentVersion: "1.45.4"
247085
+ currentVersion: "1.45.6"
247030
247086
  });
247031
247087
  return "in_progress";
247032
247088
  }
@@ -247035,7 +247091,7 @@ async function installGlobalPackage(specificVersion) {
247035
247091
  if (!env2.isRunningWithBun() && env2.isNpmFromWindowsPath()) {
247036
247092
  logError2(new Error("Windows NPM detected in WSL environment"));
247037
247093
  logEvent("tengu_auto_updater_windows_npm_in_wsl", {
247038
- currentVersion: "1.45.4"
247094
+ currentVersion: "1.45.6"
247039
247095
  });
247040
247096
  console.error(`
247041
247097
  Error: Windows NPM detected in WSL
@@ -247570,7 +247626,7 @@ function detectLinuxGlobPatternWarnings() {
247570
247626
  }
247571
247627
  async function getDoctorDiagnostic() {
247572
247628
  const installationType = await getCurrentInstallationType();
247573
- const version2 = typeof MACRO !== "undefined" ? "1.45.4" : "unknown";
247629
+ const version2 = typeof MACRO !== "undefined" ? "1.45.6" : "unknown";
247574
247630
  const installationPath = await getInstallationPath();
247575
247631
  const invokedBinary = getInvokedBinary();
247576
247632
  const multipleInstallations = await detectMultipleInstallations();
@@ -248505,8 +248561,8 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
248505
248561
  const maxVersion = await getMaxVersion();
248506
248562
  if (maxVersion && gt(version2, maxVersion)) {
248507
248563
  logForDebugging(`Native installer: maxVersion ${maxVersion} is set, capping update from ${version2} to ${maxVersion}`);
248508
- if (gte("1.45.4", maxVersion)) {
248509
- logForDebugging(`Native installer: current version ${"1.45.4"} is already at or above maxVersion ${maxVersion}, skipping update`);
248564
+ if (gte("1.45.6", maxVersion)) {
248565
+ logForDebugging(`Native installer: current version ${"1.45.6"} is already at or above maxVersion ${maxVersion}, skipping update`);
248510
248566
  logEvent("tengu_native_update_skipped_max_version", {
248511
248567
  latency_ms: Date.now() - startTime,
248512
248568
  max_version: maxVersion,
@@ -248517,7 +248573,7 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
248517
248573
  version2 = maxVersion;
248518
248574
  }
248519
248575
  }
248520
- if (!forceReinstall && version2 === "1.45.4" && await versionIsAvailable(version2) && await isPossibleURBinary(executablePath)) {
248576
+ if (!forceReinstall && version2 === "1.45.6" && await versionIsAvailable(version2) && await isPossibleURBinary(executablePath)) {
248521
248577
  logForDebugging(`Found ${version2} at ${executablePath}, skipping install`);
248522
248578
  logEvent("tengu_native_update_complete", {
248523
248579
  latency_ms: Date.now() - startTime,
@@ -346377,7 +346433,7 @@ function Feedback({
346377
346433
  platform: env2.platform,
346378
346434
  gitRepo: envInfo.isGit,
346379
346435
  terminal: env2.terminal,
346380
- version: "1.45.4",
346436
+ version: "1.45.6",
346381
346437
  transcript: normalizeMessagesForAPI(messages),
346382
346438
  errors: sanitizedErrors,
346383
346439
  lastApiRequest: getLastAPIRequest(),
@@ -346569,7 +346625,7 @@ function Feedback({
346569
346625
  ", ",
346570
346626
  env2.terminal,
346571
346627
  ", v",
346572
- "1.45.4"
346628
+ "1.45.6"
346573
346629
  ]
346574
346630
  }, undefined, true, undefined, this)
346575
346631
  ]
@@ -346675,7 +346731,7 @@ ${sanitizedDescription}
346675
346731
  ` + `**Environment Info**
346676
346732
  ` + `- Platform: ${env2.platform}
346677
346733
  ` + `- Terminal: ${env2.terminal}
346678
- ` + `- Version: ${"1.45.4"}
346734
+ ` + `- Version: ${"1.45.6"}
346679
346735
  ` + `- Feedback ID: ${feedbackId}
346680
346736
  ` + `
346681
346737
  **Errors**
@@ -349786,7 +349842,7 @@ function buildPrimarySection() {
349786
349842
  }, undefined, false, undefined, this);
349787
349843
  return [{
349788
349844
  label: "Version",
349789
- value: "1.45.4"
349845
+ value: "1.45.6"
349790
349846
  }, {
349791
349847
  label: "Session name",
349792
349848
  value: nameValue
@@ -353116,7 +353172,7 @@ function Config({
353116
353172
  }
353117
353173
  }, undefined, false, undefined, this)
353118
353174
  }, undefined, false, undefined, this) : showSubmenu === "ChannelDowngrade" ? /* @__PURE__ */ jsx_dev_runtime178.jsxDEV(ChannelDowngradeDialog, {
353119
- currentVersion: "1.45.4",
353175
+ currentVersion: "1.45.6",
353120
353176
  onChoice: (choice) => {
353121
353177
  setShowSubmenu(null);
353122
353178
  setTabsHidden(false);
@@ -353128,7 +353184,7 @@ function Config({
353128
353184
  autoUpdatesChannel: "stable"
353129
353185
  };
353130
353186
  if (choice === "stay") {
353131
- newSettings.minimumVersion = "1.45.4";
353187
+ newSettings.minimumVersion = "1.45.6";
353132
353188
  }
353133
353189
  updateSettingsForSource("userSettings", newSettings);
353134
353190
  setSettingsData((prev_27) => ({
@@ -361198,7 +361254,7 @@ function HelpV2(t0) {
361198
361254
  let t6;
361199
361255
  if ($3[31] !== tabs) {
361200
361256
  t6 = /* @__PURE__ */ jsx_dev_runtime205.jsxDEV(Tabs, {
361201
- title: `UR v${"1.45.4"}`,
361257
+ title: `UR v${"1.45.6"}`,
361202
361258
  color: "professionalBlue",
361203
361259
  defaultTab: "general",
361204
361260
  children: tabs
@@ -361972,7 +362028,7 @@ function buildToolUseContext(tools, readFileStateCache) {
361972
362028
  async function handleInitialize(options2) {
361973
362029
  return {
361974
362030
  name: "UR",
361975
- version: "1.45.4",
362031
+ version: "1.45.6",
361976
362032
  protocolVersion: "0.1.0",
361977
362033
  workspaceRoot: options2.cwd,
361978
362034
  capabilities: {
@@ -382114,7 +382170,7 @@ function getAllReleaseNotes(changelogContent = getStoredChangelogFromMemory()) {
382114
382170
  return [];
382115
382171
  }
382116
382172
  }
382117
- async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.45.4") {
382173
+ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.45.6") {
382118
382174
  if (process.env.USER_TYPE === "ant") {
382119
382175
  const changelog = "";
382120
382176
  if (changelog) {
@@ -382141,7 +382197,7 @@ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.45.4")
382141
382197
  releaseNotes
382142
382198
  };
382143
382199
  }
382144
- function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.45.4") {
382200
+ function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.45.6") {
382145
382201
  if (process.env.USER_TYPE === "ant") {
382146
382202
  const changelog = "";
382147
382203
  if (changelog) {
@@ -385233,7 +385289,7 @@ function getRecentActivitySync() {
385233
385289
  return cachedActivity;
385234
385290
  }
385235
385291
  function getLogoDisplayData() {
385236
- const version2 = process.env.DEMO_VERSION ?? "1.45.4";
385292
+ const version2 = process.env.DEMO_VERSION ?? "1.45.6";
385237
385293
  const serverUrl = getDirectConnectServerUrl();
385238
385294
  const displayPath = process.env.DEMO_VERSION ? "/code/ur" : getDisplayPath(getCwd());
385239
385295
  const cwd2 = serverUrl ? `${displayPath} in ${serverUrl.replace(/^https?:\/\//, "")}` : displayPath;
@@ -386117,7 +386173,7 @@ function LogoV2() {
386117
386173
  if ($3[2] === Symbol.for("react.memo_cache_sentinel")) {
386118
386174
  t2 = () => {
386119
386175
  const currentConfig2 = getGlobalConfig();
386120
- if (currentConfig2.lastReleaseNotesSeen === "1.45.4") {
386176
+ if (currentConfig2.lastReleaseNotesSeen === "1.45.6") {
386121
386177
  return;
386122
386178
  }
386123
386179
  saveGlobalConfig(_temp327);
@@ -386802,12 +386858,12 @@ function LogoV2() {
386802
386858
  return t41;
386803
386859
  }
386804
386860
  function _temp327(current) {
386805
- if (current.lastReleaseNotesSeen === "1.45.4") {
386861
+ if (current.lastReleaseNotesSeen === "1.45.6") {
386806
386862
  return current;
386807
386863
  }
386808
386864
  return {
386809
386865
  ...current,
386810
- lastReleaseNotesSeen: "1.45.4"
386866
+ lastReleaseNotesSeen: "1.45.6"
386811
386867
  };
386812
386868
  }
386813
386869
  function _temp243(s_0) {
@@ -604850,7 +604906,7 @@ async function captureMemoryDiagnostics(trigger2, dumpNumber = 0) {
604850
604906
  smapsRollup,
604851
604907
  platform: process.platform,
604852
604908
  nodeVersion: process.version,
604853
- ccVersion: "1.45.4"
604909
+ ccVersion: "1.45.6"
604854
604910
  };
604855
604911
  }
604856
604912
  async function performHeapDump(trigger2 = "manual", dumpNumber = 0) {
@@ -605436,7 +605492,7 @@ var init_bridge_kick = __esm(() => {
605436
605492
  var call143 = async () => {
605437
605493
  return {
605438
605494
  type: "text",
605439
- value: "1.45.4"
605495
+ value: "1.45.6"
605440
605496
  };
605441
605497
  }, version2, version_default;
605442
605498
  var init_version = __esm(() => {
@@ -616546,7 +616602,7 @@ function generateHtmlReport(data, insights) {
616546
616602
  </html>`;
616547
616603
  }
616548
616604
  function buildExportData(data, insights, facets, remoteStats) {
616549
- const version3 = typeof MACRO !== "undefined" ? "1.45.4" : "unknown";
616605
+ const version3 = typeof MACRO !== "undefined" ? "1.45.6" : "unknown";
616550
616606
  const remote_hosts_collected = remoteStats?.hosts.filter((h2) => h2.sessionCount > 0).map((h2) => h2.name);
616551
616607
  const facets_summary = {
616552
616608
  total: facets.size,
@@ -620875,7 +620931,7 @@ var init_sessionStorage = __esm(() => {
620875
620931
  init_settings2();
620876
620932
  init_slowOperations();
620877
620933
  init_uuid();
620878
- VERSION5 = typeof MACRO !== "undefined" ? "1.45.4" : "unknown";
620934
+ VERSION5 = typeof MACRO !== "undefined" ? "1.45.6" : "unknown";
620879
620935
  MAX_TOMBSTONE_REWRITE_BYTES = 50 * 1024 * 1024;
620880
620936
  SKIP_FIRST_PROMPT_PATTERN = /^(?:\s*<[a-z][\w-]*[\s>]|\[Request interrupted by user[^\]]*\])/;
620881
620937
  EPHEMERAL_PROGRESS_TYPES = new Set([
@@ -622080,7 +622136,7 @@ var init_filesystem = __esm(() => {
622080
622136
  });
622081
622137
  getBundledSkillsRoot = memoize_default(function getBundledSkillsRoot2() {
622082
622138
  const nonce = randomBytes18(16).toString("hex");
622083
- return join211(getURTempDir(), "bundled-skills", "1.45.4", nonce);
622139
+ return join211(getURTempDir(), "bundled-skills", "1.45.6", nonce);
622084
622140
  });
622085
622141
  getResolvedWorkingDirPaths = memoize_default(getPathsForPermissionCheck);
622086
622142
  });
@@ -628375,7 +628431,7 @@ function computeFingerprint(messageText2, version3) {
628375
628431
  }
628376
628432
  function computeFingerprintFromMessages(messages) {
628377
628433
  const firstMessageText = extractFirstMessageText(messages);
628378
- return computeFingerprint(firstMessageText, "1.45.4");
628434
+ return computeFingerprint(firstMessageText, "1.45.6");
628379
628435
  }
628380
628436
  var FINGERPRINT_SALT = "59cf53e54c78";
628381
628437
  var init_fingerprint = () => {};
@@ -628763,14 +628819,20 @@ function shouldDeferLspTool(tool) {
628763
628819
  const status2 = getInitializationStatus();
628764
628820
  return status2.status === "pending" || status2.status === "not-started";
628765
628821
  }
628766
- function getNonstreamingFallbackTimeoutMs() {
628767
- const override = parseInt(process.env.API_TIMEOUT_MS || "", 10);
628822
+ function isOllamaCloudRuntime(model, provider = getAPIProvider()) {
628823
+ return provider === "ollama" && model.trim().toLowerCase().endsWith(":cloud");
628824
+ }
628825
+ function getNonstreamingFallbackTimeoutMs(model, env4 = process.env, provider = getAPIProvider()) {
628826
+ const override = parseInt(env4.API_TIMEOUT_MS || "", 10);
628768
628827
  if (override)
628769
628828
  return override;
628770
- return isEnvTruthy(process.env.UR_CODE_REMOTE) ? 120000 : 300000;
628829
+ return isEnvTruthy(env4.UR_CODE_REMOTE) || isOllamaCloudRuntime(model, provider) ? 120000 : 300000;
628830
+ }
628831
+ function shouldSkipOllamaNonStreamingFallback(error40, model, provider = getAPIProvider()) {
628832
+ return isOllamaCloudRuntime(model, provider) && error40 instanceof APIConnectionTimeoutError && error40.message === "Ollama stream timed out";
628771
628833
  }
628772
628834
  async function* executeNonStreamingRequest(clientOptions, retryOptions, paramsFromContext, onAttempt, captureRequest, originatingRequestId) {
628773
- const fallbackTimeoutMs = getNonstreamingFallbackTimeoutMs();
628835
+ const fallbackTimeoutMs = getNonstreamingFallbackTimeoutMs(clientOptions.model);
628774
628836
  const generator = withRetry(() => getURHQClient({
628775
628837
  maxRetries: 0,
628776
628838
  model: clientOptions.model,
@@ -628804,6 +628866,7 @@ async function* executeNonStreamingRequest(clientOptions, retryOptions, paramsFr
628804
628866
  throw err2;
628805
628867
  }
628806
628868
  }, {
628869
+ ...isOllamaCloudRuntime(retryOptions.model) ? { maxRetries: 0 } : {},
628807
628870
  model: retryOptions.model,
628808
628871
  fallbackModel: retryOptions.fallbackModel,
628809
628872
  thinkingConfig: retryOptions.thinkingConfig,
@@ -629283,6 +629346,7 @@ ${deferredToolList}
629283
629346
  streamResponse = result.response;
629284
629347
  return result.data;
629285
629348
  }, {
629349
+ ...isOllamaCloudRuntime(options2.model) ? { maxRetries: 0 } : {},
629286
629350
  model: options2.model,
629287
629351
  fallbackModel: options2.fallbackModel,
629288
629352
  thinkingConfig,
@@ -629627,6 +629691,9 @@ ${deferredToolList}
629627
629691
  throw new APIConnectionTimeoutError({ message: "Request timed out" });
629628
629692
  }
629629
629693
  }
629694
+ if (shouldSkipOllamaNonStreamingFallback(streamingError, options2.model)) {
629695
+ throw streamingError;
629696
+ }
629630
629697
  const disableFallback = isEnvTruthy(process.env.UR_CODE_DISABLE_NONSTREAMING_FALLBACK) || getFeatureValue_CACHED_MAY_BE_STALE("tengu_disable_streaming_to_non_streaming_fallback", false);
629631
629698
  if (disableFallback) {
629632
629699
  logForDebugging(`Error streaming (non-streaming fallback disabled): ${errorMessage2(streamingError)}`, { level: "error" });
@@ -630249,7 +630316,7 @@ async function sideQuery(opts) {
630249
630316
  betas.push(STRUCTURED_OUTPUTS_BETA_HEADER);
630250
630317
  }
630251
630318
  const messageText2 = extractFirstUserMessageText(messages);
630252
- const fingerprint2 = computeFingerprint(messageText2, "1.45.4");
630319
+ const fingerprint2 = computeFingerprint(messageText2, "1.45.6");
630253
630320
  const attributionHeader = getAttributionHeader(fingerprint2);
630254
630321
  const systemBlocks = [
630255
630322
  attributionHeader ? { type: "text", text: attributionHeader } : null,
@@ -634986,7 +635053,7 @@ function buildSystemInitMessage(inputs) {
634986
635053
  slash_commands: inputs.commands.filter((c4) => c4.userInvocable !== false).map((c4) => c4.name),
634987
635054
  apiKeySource: getURHQApiKeyWithSource().source,
634988
635055
  betas: getSdkBetas(),
634989
- ur_version: "1.45.4",
635056
+ ur_version: "1.45.6",
634990
635057
  output_style: outputStyle2,
634991
635058
  agents: inputs.agents.map((agent) => agent.agentType),
634992
635059
  skills: inputs.skills.filter((s) => s.userInvocable !== false).map((skill2) => skill2.name),
@@ -648846,7 +648913,7 @@ var init_useVoiceEnabled = __esm(() => {
648846
648913
  function getSemverPart(version3) {
648847
648914
  return `${import_semver13.major(version3, { loose: true })}.${import_semver13.minor(version3, { loose: true })}.${import_semver13.patch(version3, { loose: true })}`;
648848
648915
  }
648849
- function useUpdateNotification(updatedVersion, initialVersion = "1.45.4") {
648916
+ function useUpdateNotification(updatedVersion, initialVersion = "1.45.6") {
648850
648917
  const [lastNotifiedSemver, setLastNotifiedSemver] = import_react228.useState(() => getSemverPart(initialVersion));
648851
648918
  if (!updatedVersion) {
648852
648919
  return null;
@@ -648895,7 +648962,7 @@ function AutoUpdater({
648895
648962
  return;
648896
648963
  }
648897
648964
  if (false) {}
648898
- const currentVersion = "1.45.4";
648965
+ const currentVersion = "1.45.6";
648899
648966
  const channel = getInitialSettings()?.autoUpdatesChannel ?? "latest";
648900
648967
  let latestVersion = await getLatestVersion(channel);
648901
648968
  const isDisabled = isAutoUpdaterDisabled();
@@ -649124,12 +649191,12 @@ function NativeAutoUpdater({
649124
649191
  logEvent("tengu_native_auto_updater_start", {});
649125
649192
  try {
649126
649193
  const maxVersion = await getMaxVersion();
649127
- if (maxVersion && gt("1.45.4", maxVersion)) {
649194
+ if (maxVersion && gt("1.45.6", maxVersion)) {
649128
649195
  const msg = await getMaxVersionMessage();
649129
649196
  setMaxVersionIssue(msg ?? "affects your version");
649130
649197
  }
649131
649198
  const result = await installLatest(channel);
649132
- const currentVersion = "1.45.4";
649199
+ const currentVersion = "1.45.6";
649133
649200
  const latencyMs = Date.now() - startTime;
649134
649201
  if (result.lockFailed) {
649135
649202
  logEvent("tengu_native_auto_updater_lock_contention", {
@@ -649266,17 +649333,17 @@ function PackageManagerAutoUpdater(t0) {
649266
649333
  const maxVersion = await getMaxVersion();
649267
649334
  if (maxVersion && latest && gt(latest, maxVersion)) {
649268
649335
  logForDebugging(`PackageManagerAutoUpdater: maxVersion ${maxVersion} is set, capping update from ${latest} to ${maxVersion}`);
649269
- if (gte("1.45.4", maxVersion)) {
649270
- logForDebugging(`PackageManagerAutoUpdater: current version ${"1.45.4"} is already at or above maxVersion ${maxVersion}, skipping update`);
649336
+ if (gte("1.45.6", maxVersion)) {
649337
+ logForDebugging(`PackageManagerAutoUpdater: current version ${"1.45.6"} is already at or above maxVersion ${maxVersion}, skipping update`);
649271
649338
  setUpdateAvailable(false);
649272
649339
  return;
649273
649340
  }
649274
649341
  latest = maxVersion;
649275
649342
  }
649276
- const hasUpdate = latest && !gte("1.45.4", latest) && !shouldSkipVersion(latest);
649343
+ const hasUpdate = latest && !gte("1.45.6", latest) && !shouldSkipVersion(latest);
649277
649344
  setUpdateAvailable(!!hasUpdate);
649278
649345
  if (hasUpdate) {
649279
- logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.45.4"} -> ${latest}`);
649346
+ logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.45.6"} -> ${latest}`);
649280
649347
  }
649281
649348
  };
649282
649349
  $3[0] = t1;
@@ -649310,7 +649377,7 @@ function PackageManagerAutoUpdater(t0) {
649310
649377
  wrap: "truncate",
649311
649378
  children: [
649312
649379
  "currentVersion: ",
649313
- "1.45.4"
649380
+ "1.45.6"
649314
649381
  ]
649315
649382
  }, undefined, true, undefined, this);
649316
649383
  $3[3] = verbose;
@@ -660007,7 +660074,7 @@ function buildStatusLineCommandInput(permissionMode, exceeds200kTokens, settings
660007
660074
  project_dir: getOriginalCwd(),
660008
660075
  added_dirs: addedDirs
660009
660076
  },
660010
- version: "1.45.4",
660077
+ version: "1.45.6",
660011
660078
  output_style: {
660012
660079
  name: outputStyleName
660013
660080
  },
@@ -660090,7 +660157,7 @@ function StatusLineInner({
660090
660157
  const taskValues = Object.values(tasks2);
660091
660158
  const taskRunningCount = taskValues.filter((task2) => task2.status === "running" || task2.status === "pending").length;
660092
660159
  const defaultStatusLineText = buildDefaultStatusBar({
660093
- version: "1.45.4",
660160
+ version: "1.45.6",
660094
660161
  providerLabel: providerRuntime.providerLabel,
660095
660162
  authMode: providerRuntime.authLabel,
660096
660163
  model: providerRuntime.model ?? renderModelName(mainLoopModel),
@@ -672083,7 +672150,7 @@ async function submitTranscriptShare(messages, trigger2, appearanceId) {
672083
672150
  } catch {}
672084
672151
  const data = {
672085
672152
  trigger: trigger2,
672086
- version: "1.45.4",
672153
+ version: "1.45.6",
672087
672154
  platform: process.platform,
672088
672155
  transcript,
672089
672156
  subagentTranscripts: Object.keys(subagentTranscripts).length > 0 ? subagentTranscripts : undefined,
@@ -684369,7 +684436,7 @@ function WelcomeV2() {
684369
684436
  dimColor: true,
684370
684437
  children: [
684371
684438
  "v",
684372
- "1.45.4"
684439
+ "1.45.6"
684373
684440
  ]
684374
684441
  }, undefined, true, undefined, this)
684375
684442
  ]
@@ -685629,7 +685696,7 @@ function completeOnboarding() {
685629
685696
  saveGlobalConfig((current) => ({
685630
685697
  ...current,
685631
685698
  hasCompletedOnboarding: true,
685632
- lastOnboardingVersion: "1.45.4"
685699
+ lastOnboardingVersion: "1.45.6"
685633
685700
  }));
685634
685701
  }
685635
685702
  function showDialog(root2, renderer) {
@@ -690651,7 +690718,7 @@ function appendToLog(path24, message) {
690651
690718
  cwd: getFsImplementation().cwd(),
690652
690719
  userType: process.env.USER_TYPE,
690653
690720
  sessionId: getSessionId(),
690654
- version: "1.45.4"
690721
+ version: "1.45.6"
690655
690722
  };
690656
690723
  getLogWriter(path24).write(messageWithTimestamp);
690657
690724
  }
@@ -694810,8 +694877,8 @@ async function getEnvLessBridgeConfig() {
694810
694877
  }
694811
694878
  async function checkEnvLessBridgeMinVersion() {
694812
694879
  const cfg = await getEnvLessBridgeConfig();
694813
- if (cfg.min_version && lt("1.45.4", cfg.min_version)) {
694814
- return `Your version of UR (${"1.45.4"}) is too old for Remote Control.
694880
+ if (cfg.min_version && lt("1.45.6", cfg.min_version)) {
694881
+ return `Your version of UR (${"1.45.6"}) is too old for Remote Control.
694815
694882
  Version ${cfg.min_version} or higher is required. Run \`ur update\` to update.`;
694816
694883
  }
694817
694884
  return null;
@@ -695285,7 +695352,7 @@ async function initBridgeCore(params) {
695285
695352
  const rawApi = createBridgeApiClient({
695286
695353
  baseUrl,
695287
695354
  getAccessToken,
695288
- runnerVersion: "1.45.4",
695355
+ runnerVersion: "1.45.6",
695289
695356
  onDebug: logForDebugging,
695290
695357
  onAuth401,
695291
695358
  getTrustedDeviceToken
@@ -700967,7 +701034,7 @@ async function startMCPServer(cwd3, debug2, verbose) {
700967
701034
  setCwd(cwd3);
700968
701035
  const server2 = new Server({
700969
701036
  name: "ur/tengu",
700970
- version: "1.45.4"
701037
+ version: "1.45.6"
700971
701038
  }, {
700972
701039
  capabilities: {
700973
701040
  tools: {}
@@ -703009,7 +703076,7 @@ async function update() {
703009
703076
  logEvent("tengu_update_check", {});
703010
703077
  const diagnostic = await getDoctorDiagnostic();
703011
703078
  const result = await checkUpgradeStatus({
703012
- currentVersion: "1.45.4",
703079
+ currentVersion: "1.45.6",
703013
703080
  packageName: UR_AGENT_PACKAGE_NAME,
703014
703081
  installationType: diagnostic.installationType,
703015
703082
  latestVersion: () => getLatestNpmPackageVersion(UR_AGENT_PACKAGE_NAME)
@@ -704320,7 +704387,7 @@ ${customInstructions}` : customInstructions;
704320
704387
  }
704321
704388
  }
704322
704389
  logForDiagnosticsNoPII("info", "started", {
704323
- version: "1.45.4",
704390
+ version: "1.45.6",
704324
704391
  is_native_binary: isInBundledMode()
704325
704392
  });
704326
704393
  registerCleanup(async () => {
@@ -705106,7 +705173,7 @@ Usage: ur --remote "your task description"`, () => gracefulShutdown(1));
705106
705173
  pendingHookMessages
705107
705174
  }, renderAndRun);
705108
705175
  }
705109
- }).version("1.45.4 (UR-Nexus)", "-v, --version", "Output the version number");
705176
+ }).version("1.45.6 (UR-Nexus)", "-v, --version", "Output the version number");
705110
705177
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
705111
705178
  program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
705112
705179
  if (canUserConfigureAdvisor()) {
@@ -706042,7 +706109,7 @@ if (false) {}
706042
706109
  async function main2() {
706043
706110
  const args = process.argv.slice(2);
706044
706111
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
706045
- console.log(`${"1.45.4"} (UR-Nexus)`);
706112
+ console.log(`${"1.45.6"} (UR-Nexus)`);
706046
706113
  return;
706047
706114
  }
706048
706115
  if (args[0] === "a2a" && args[1] === "serve" && !args.includes("--help") && !args.includes("-h")) {
@@ -9,6 +9,21 @@ reproducible autonomous software engineering agent: every substantial task can
9
9
  be driven as `spec -> plan -> patch -> test -> report -> rollback`, with the
10
10
  spec as the durable source of truth and command evidence as the success gate.
11
11
 
12
+ ## v1.45.6 Additions
13
+
14
+ - Project verification approval is deduplicated per user turn. The agent asks
15
+ once before the final compile/test/lint commands, then respects that decision
16
+ without presenting the same gate again.
17
+
18
+ ## v1.45.5 Additions
19
+
20
+ - Ollama Cloud requests have bounded response-header and streaming phases and
21
+ do not amplify a deliberate stream timeout through fallback retries. Local
22
+ model timing and explicit timeout overrides are unchanged.
23
+ - The verifier now recognizes terminal promises such as "Let me create it
24
+ now" or "I will run the tests now" and requires the corresponding successful
25
+ mutation or Bash call before the turn may complete.
26
+
12
27
  ## Commands
13
28
 
14
29
  ```sh
@@ -311,7 +311,7 @@ Behaviour is controlled by environment variables:
311
311
  ```sh
312
312
  # Overall mode (default: strict) — controls the L1 gates
313
313
  UR_VERIFIER_MODE=strict # all L1 gates on: done-claim, loops, empty turn,
314
- # project gates
314
+ # project gates; approval is requested once per user turn
315
315
  UR_VERIFIER_MODE=loose # only empty-turn check + loop detector
316
316
  UR_VERIFIER_MODE=off # disable verifier entirely
317
317
 
package/docs/USAGE.md CHANGED
@@ -100,6 +100,16 @@ use `ollama.host` in settings if you want plain `ur` to default to a LAN host.
100
100
  Models exposed by the chosen Ollama app are valid, including local models and
101
101
  Ollama Cloud-backed models.
102
102
 
103
+ Ollama Cloud models use a 120-second default bound for both response-header
104
+ waiting and stream consumption. A deliberate stream deadline is returned
105
+ directly instead of being replayed through the non-streaming fallback. Local
106
+ Ollama models keep the five-minute default. Set `API_TIMEOUT_MS` to explicitly
107
+ override either default for the current process.
108
+
109
+ When project verification requires approval, UR asks once per user turn. The
110
+ same pending compile/test/lint gate is not presented again after the user has
111
+ answered; a later user task can request its own approval normally.
112
+
103
113
  UR-Nexus also has explicit provider commands for legal access paths:
104
114
 
105
115
  ```sh
@@ -19,7 +19,7 @@ You need:
19
19
 
20
20
  ```sh
21
21
  ur --version
22
- # expected for this release: "1.45.4 (UR-Nexus)"
22
+ # expected for this release: "1.45.6 (UR-Nexus)"
23
23
  ```
24
24
 
25
25
  ## 0.1 First-workspace model selection (1.45.4)
@@ -40,6 +40,27 @@ ur -p "say hi"
40
40
  Expected: `No model has been selected for this workspace`. Supplying
41
41
  `--model <model>`, `OLLAMA_MODEL`, or `UR_MODEL` bypasses the gate for that run.
42
42
 
43
+ ### 0.1.1 Ollama Cloud latency containment (1.45.5)
44
+
45
+ Run the deterministic regression coverage:
46
+
47
+ ```sh
48
+ bun test test/ollamaTimeout.test.ts
49
+ ```
50
+
51
+ Expected: the cloud-model timeout, override-precedence, stream-deadline, and
52
+ fallback-suppression cases pass. A model ending in `:cloud` defaults to 120
53
+ seconds for response headers and streaming; a local model retains 300 seconds.
54
+ `API_TIMEOUT_MS` wins over both. When a cloud stream reaches its deliberate
55
+ deadline, the request fails once instead of starting a non-streaming replay.
56
+
57
+ ### 0.1.2 Single project-gate approval (1.45.6)
58
+
59
+ With `verifier.askBeforeGates` enabled, complete a task that edits a source
60
+ file. Expected: UR asks once whether to run the detected compile/test/lint
61
+ commands. After answering, the same approval question is not shown again. A
62
+ separate user task that edits files may ask once for its own verification.
63
+
43
64
  ## 0.2 Permission safety and context pack (1.19.0)
44
65
 
45
66
  In a project checkout:
@@ -186,6 +207,11 @@ Expected:
186
207
  UR_VERIFIER_MODE=strict ur # default, false claim rejected
187
208
  ```
188
209
 
210
+ Also prompt the model to end with `Let me create index.html now.` while
211
+ forbidding tool calls. Strict mode must inject a correction and continue rather
212
+ than accepting the promise as completion. Conditional text such as `If you
213
+ approve, I'll create it` must not trigger this gate.
214
+
189
215
  ## 3. L1 loop detector fires
190
216
 
191
217
  ```text
package/docs/providers.md CHANGED
@@ -431,6 +431,13 @@ Local/server providers use their normal endpoints:
431
431
  - llama.cpp server mode: `http://localhost:8080/v1`
432
432
  - vLLM server mode: `http://localhost:8000/v1`
433
433
 
434
+ Ollama models whose names end in `:cloud` use a 120-second default for the
435
+ response-header phase and a 120-second total stream deadline. UR does not
436
+ automatically replay a cloud request after that stream deadline, preventing a
437
+ bounded failure from expanding into the shared non-streaming fallback and
438
+ retry chain. Local Ollama models retain the five-minute default. A positive
439
+ `API_TIMEOUT_MS` or explicit request timeout overrides these defaults.
440
+
434
441
  ## Optional Live Provider Smoke
435
442
 
436
443
  `bun run provider:smoke` runs optional live checks only for providers with the
@@ -44,7 +44,7 @@
44
44
  <main id="content" class="content">
45
45
  <header class="topbar">
46
46
  <div>
47
- <p class="eyebrow">Version 1.45.4</p>
47
+ <p class="eyebrow">Version 1.45.6</p>
48
48
  <h1>UR-Nexus Documentation</h1>
49
49
  <p class="lead">A practical, tutorial-style reference for installing, configuring, automating, extending, and operating UR-Nexus.</p>
50
50
  </div>
@@ -163,9 +163,14 @@ ur config set provider.fallback ollama</code></pre>
163
163
  </article>
164
164
  <article>
165
165
  <h3>Status bar and updates</h3>
166
- <pre><code>Ollama | llama3 | ask | main | update 1.45.4 available</code></pre>
166
+ <pre><code>Ollama | llama3 | ask | main | update 1.45.6 available</code></pre>
167
167
  <p>The interactive status bar shows only important runtime state: provider, model, mode, branch, active tasks, checks status when known, and update availability. It is hidden in CI, dumb terminals, and print mode.</p>
168
168
  </article>
169
+ <article>
170
+ <h3>Ollama Cloud latency bounds</h3>
171
+ <pre><code>API_TIMEOUT_MS=120000 ur</code></pre>
172
+ <p>Cloud-tagged Ollama models default to bounded response-header and streaming phases. A stream deadline is surfaced directly instead of starting a non-streaming retry chain. Local models retain their longer default, and <code>API_TIMEOUT_MS</code> remains an explicit override.</p>
173
+ </article>
169
174
  </div>
170
175
  </section>
171
176
 
@@ -481,8 +486,8 @@ ur context-pack compress</code></pre>
481
486
  UR_VERIFIER_MODE=loose
482
487
  UR_VERIFIER_MODE=off
483
488
  UR_VERIFIER_AUTO_SUBAGENT=1</code></pre>
484
- <p>L1 gates catch false done claims and loops. <code>/verify</code> manually runs deeper verification.</p>
485
- <p>Interactive users can set <code>"verifier": { "askBeforeGates": true }</code> in <code>.ur/settings.json</code> (or via <code>ur config set verifier.askBeforeGates true</code>) to have UR ask before running project test/typecheck/lint gates after a task, instead of running them automatically. Default is <code>false</code> (auto-run gates).</p>
489
+ <p>L1 gates catch false done claims, immediate-action promises that end without their tool call, and loops. <code>/verify</code> manually runs deeper verification.</p>
490
+ <p>Interactive users can set <code>"verifier": { "askBeforeGates": true }</code> in <code>.ur/settings.json</code> (or via <code>ur config set verifier.askBeforeGates true</code>) to have UR ask once per user turn before running project test/typecheck/lint gates after a task, instead of running them automatically. Default is <code>false</code> (auto-run gates).</p>
486
491
  </article>
487
492
  <article>
488
493
  <h3>MCP and plugins</h3>
@@ -5,7 +5,7 @@ plugins {
5
5
  }
6
6
 
7
7
  group = "dev.urnexus"
8
- version = "1.45.4"
8
+ version = "1.45.6"
9
9
 
10
10
  repositories {
11
11
  mavenCentral()
@@ -2,7 +2,7 @@
2
2
  "name": "ur-inline-diffs",
3
3
  "displayName": "UR Inline Diffs",
4
4
  "description": "Review, apply, and reject UR inline diff bundles from .ur/ide/diffs inside VS Code.",
5
- "version": "1.45.4",
5
+ "version": "1.45.6",
6
6
  "publisher": "ur-nexus",
7
7
  "engines": {
8
8
  "vscode": "^1.92.0"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ur-agent",
3
- "version": "1.45.4",
3
+ "version": "1.45.6",
4
4
  "description": "UR-Nexus — autonomous engineering workflow engine (plan, execute, test, verify, document, benchmark, reproduce)",
5
5
  "type": "module",
6
6
  "packageManager": "bun@1.3.14",