ur-agent 1.80.6 → 1.80.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.80.8
4
+
5
+ - Fixed provider-independent failed-first research delegation. Several model
6
+ families selected `general-purpose` even when their own worker brief said
7
+ read-only research, causing `TaskListRequired` before the research could
8
+ start. UR now safely downgrades that exact main-session contract to its
9
+ mechanically read-only shipped `Explore` agent before task gating.
10
+ - Strengthened the shared Agent prompt and Explore description so models choose
11
+ `subagent_type="Explore"` directly for task-free research. The compatibility
12
+ downgrade also recognizes “research task only; do not write files” wording.
13
+ - Kept the boundary fail-closed: implementation prompts, custom definitions,
14
+ nested workers, named/team agents, worktrees, cwd overrides, and every other
15
+ general-purpose call still require an actionable task. Permission and hook
16
+ rewrites are revalidated before execution. Approve All remains unchanged.
17
+
18
+ ## 1.80.7
19
+
20
+ - Fixed Ollama runs stopping with `response returned unavailable tool
21
+ "WebSearch"`. Syntactically valid but unavailable native and text-form calls
22
+ now reach UR's guarded executor, which returns a recoverable result without
23
+ executing the tool and tells the model to use an available alternative or
24
+ return useful partial work. Identical retries are bounded; malformed names
25
+ and arguments still fail closed.
26
+ - Extended task-free read-only research beyond Plan Mode. The main session may
27
+ launch UR's exact shipped `Explore` and `Plan` agents before tasks exist in
28
+ every permission mode, and those workers are forced into plan permissions
29
+ even when the parent uses Accept Edits or Approve All. Custom, write-capable,
30
+ nested, team, and worktree agents still require an actionable parent task.
31
+ - Removed the global deprecated-alias fallback from tool execution. Aliases
32
+ continue to work for tools present in the active profile, but can no longer
33
+ revive a tool deliberately omitted from a worker. Approve All itself remains
34
+ supported and unchanged.
35
+
3
36
  ## 1.80.6
4
37
 
5
38
  - Fixed Plan Mode's failed-first research delegation. UR's shipped read-only
package/dist/cli.js CHANGED
@@ -88903,6 +88903,9 @@ function parseTextToolCalls(text, options = {}) {
88903
88903
  return call;
88904
88904
  const name = reconcileToolName(call.name, options.availableToolNames);
88905
88905
  if (!hasTool(options.availableToolNames, name)) {
88906
+ if (options.preserveUnavailableToolCalls) {
88907
+ return name === call.name ? call : { ...call, name };
88908
+ }
88906
88909
  throw new KimiToolCallParseError(`Kimi returned unavailable tool "${name}"`);
88907
88910
  }
88908
88911
  return name === call.name ? call : { ...call, name };
@@ -90333,7 +90336,8 @@ function ollamaResponseToURHQMessage(response, params, textToolFallbackAllowed)
90333
90336
  const rawText = response.message?.content ?? "";
90334
90337
  const parsedText = textToolFallbackAllowed ? parseTextToolCalls(rawText, {
90335
90338
  availableToolNames,
90336
- parseBareJsonToolCalls: true
90339
+ parseBareJsonToolCalls: true,
90340
+ preserveUnavailableToolCalls: true
90337
90341
  }) : { text: rawText, toolCalls: [] };
90338
90342
  const text = parsedText.text;
90339
90343
  const textToolCalls = [...parsedText.toolCalls];
@@ -90423,7 +90427,7 @@ function normalizeOllamaToolUses(structured, textCalls, availableToolNames, cont
90423
90427
  }
90424
90428
  const name = reconcileToolName(rawName, availableToolNames);
90425
90429
  if (!availableToolNames.has(name)) {
90426
- throw new ProviderResponseParseError(`${context} returned unavailable tool "${name}"`, { rawName, availableToolNames: [...availableToolNames] });
90430
+ logForDebugging(`${context} preserved unavailable tool "${name}" for guarded rejection`, { level: "warn" });
90427
90431
  }
90428
90432
  const key = `${name}\x00${toolArgsKey(input)}`;
90429
90433
  if (seen.has(key)) {
@@ -107784,7 +107788,7 @@ var init_auth = __esm(() => {
107784
107788
 
107785
107789
  // src/utils/userAgent.ts
107786
107790
  function getURCodeUserAgent() {
107787
- return `ur/${"1.80.6"}`;
107791
+ return `ur/${"1.80.8"}`;
107788
107792
  }
107789
107793
 
107790
107794
  // src/utils/workloadContext.ts
@@ -107806,7 +107810,7 @@ function getUserAgent() {
107806
107810
  const clientApp = process.env.UR_AGENT_SDK_CLIENT_APP ? `, client-app/${process.env.UR_AGENT_SDK_CLIENT_APP}` : "";
107807
107811
  const workload = getWorkload();
107808
107812
  const workloadSuffix = workload ? `, workload/${workload}` : "";
107809
- return `ur-cli/${"1.80.6"} (${process.env.USER_TYPE}, ${process.env.UR_CODE_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
107813
+ return `ur-cli/${"1.80.8"} (${process.env.USER_TYPE}, ${process.env.UR_CODE_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
107810
107814
  }
107811
107815
  function getMCPUserAgent() {
107812
107816
  const parts = [];
@@ -107820,7 +107824,7 @@ function getMCPUserAgent() {
107820
107824
  parts.push(`client-app/${process.env.UR_AGENT_SDK_CLIENT_APP}`);
107821
107825
  }
107822
107826
  const suffix = parts.length > 0 ? ` (${parts.join(", ")})` : "";
107823
- return `ur/${"1.80.6"}${suffix}`;
107827
+ return `ur/${"1.80.8"}${suffix}`;
107824
107828
  }
107825
107829
  function getWebFetchUserAgent() {
107826
107830
  return `UR-User (${getURCodeUserAgent()})`;
@@ -107958,7 +107962,7 @@ var init_user = __esm(() => {
107958
107962
  deviceId,
107959
107963
  sessionId: getSessionId(),
107960
107964
  email: getEmail(),
107961
- appVersion: "1.80.6",
107965
+ appVersion: "1.80.8",
107962
107966
  platform: getHostPlatformForAnalytics(),
107963
107967
  organizationUuid,
107964
107968
  accountUuid,
@@ -115845,7 +115849,7 @@ var init_metadata = __esm(() => {
115845
115849
  COMPOUND_OPERATOR_REGEX = /\s*(?:&&|\|\||[;|])\s*/;
115846
115850
  WHITESPACE_REGEX = /\s+/;
115847
115851
  getVersionBase = memoize_default(() => {
115848
- const match = "1.80.6".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
115852
+ const match = "1.80.8".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
115849
115853
  return match ? match[0] : undefined;
115850
115854
  });
115851
115855
  buildEnvContext = memoize_default(async () => {
@@ -115885,7 +115889,7 @@ var init_metadata = __esm(() => {
115885
115889
  isGithubAction: isEnvTruthy(process.env.GITHUB_ACTIONS),
115886
115890
  isURCodeAction: isEnvTruthy(process.env.UR_CODE_ACTION),
115887
115891
  isURAiAuth: isURAISubscriber(),
115888
- version: "1.80.6",
115892
+ version: "1.80.8",
115889
115893
  versionBase: getVersionBase(),
115890
115894
  buildTime: "",
115891
115895
  deploymentEnvironment: env2.detectDeploymentEnvironment(),
@@ -116555,7 +116559,7 @@ function initialize1PEventLogging() {
116555
116559
  const platform2 = getPlatform();
116556
116560
  const attributes = {
116557
116561
  [import_semantic_conventions4.ATTR_SERVICE_NAME]: "ur",
116558
- [import_semantic_conventions4.ATTR_SERVICE_VERSION]: "1.80.6"
116562
+ [import_semantic_conventions4.ATTR_SERVICE_VERSION]: "1.80.8"
116559
116563
  };
116560
116564
  if (platform2 === "wsl") {
116561
116565
  const wslVersion = getWslVersion();
@@ -116583,7 +116587,7 @@ function initialize1PEventLogging() {
116583
116587
  })
116584
116588
  ]
116585
116589
  });
116586
- firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("com.urhq.ur.events", "1.80.6");
116590
+ firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("com.urhq.ur.events", "1.80.8");
116587
116591
  }
116588
116592
  async function reinitialize1PEventLoggingIfConfigChanged() {
116589
116593
  if (!is1PEventLoggingEnabled() || !firstPartyEventLoggerProvider) {
@@ -126546,7 +126550,7 @@ function formatA2AAgentCard(options = {}, pretty = true) {
126546
126550
  function formatA2AV1AgentCard(options = {}, pretty = true) {
126547
126551
  return JSON.stringify(buildA2AV1AgentCard(options), null, pretty ? 2 : 0);
126548
126552
  }
126549
- var urVersion = "1.80.6", researchSnapshotDate = "2026-08-10", coverage, priorityRoadmap;
126553
+ var urVersion = "1.80.8", researchSnapshotDate = "2026-08-10", coverage, priorityRoadmap;
126550
126554
  var init_trends = __esm(() => {
126551
126555
  init_a2aCardSignature();
126552
126556
  coverage = [
@@ -129436,7 +129440,7 @@ function getAttributionHeader(fingerprint) {
129436
129440
  if (!isAttributionHeaderEnabled()) {
129437
129441
  return "";
129438
129442
  }
129439
- const version2 = `${"1.80.6"}.${fingerprint}`;
129443
+ const version2 = `${"1.80.8"}.${fingerprint}`;
129440
129444
  const entrypoint = process.env.UR_CODE_ENTRYPOINT ?? "unknown";
129441
129445
  const cch = "";
129442
129446
  const workload = getWorkload();
@@ -174266,7 +174270,7 @@ NOTE: You are meant to be a fast agent that returns output as quickly as possibl
174266
174270
 
174267
174271
  Complete the user's search request efficiently and report your findings clearly.`;
174268
174272
  }
174269
- var EXPLORE_AGENT_MIN_QUERIES = 3, EXPLORE_WHEN_TO_USE = 'Fast agent specialized for exploring codebases. Use this when you need to quickly find files by patterns (eg. "src/components/**/*.tsx"), search code for keywords (eg. "API endpoints"), or answer questions about the codebase (eg. "how do API endpoints work?"). When calling this agent, specify the desired thoroughness level: "quick" for basic searches, "medium" for moderate exploration, or "very thorough" for comprehensive analysis across multiple locations and naming conventions.', EXPLORE_AGENT;
174273
+ var EXPLORE_AGENT_MIN_QUERIES = 3, EXPLORE_WHEN_TO_USE = 'Read-only research and exploration agent. Use this for external research, source gathering, audits, codebase exploration, file-pattern searches (eg. "src/components/**/*.tsx"), code searches (eg. "API endpoints"), and questions about how a repository works. Prefer this over general-purpose whenever the worker must not modify files, especially before an actionable task exists. Specify the desired thoroughness: "quick", "medium", or "very thorough".', EXPLORE_AGENT;
174270
174274
  var init_exploreAgent = __esm(() => {
174271
174275
  init_prompt3();
174272
174276
  init_prompt4();
@@ -184632,7 +184636,7 @@ var init_projectSafety = __esm(() => {
184632
184636
  function getInstruments() {
184633
184637
  if (instruments)
184634
184638
  return instruments;
184635
- const meter = import_api10.metrics.getMeter("ur-agent.gen_ai", "1.80.6");
184639
+ const meter = import_api10.metrics.getMeter("ur-agent.gen_ai", "1.80.8");
184636
184640
  instruments = {
184637
184641
  operationDuration: meter.createHistogram("gen_ai.client.operation.duration", {
184638
184642
  description: "GenAI operation duration.",
@@ -184730,7 +184734,7 @@ function genAiAgentAttributes() {
184730
184734
  "gen_ai.operation.name": GEN_AI_OPERATION_INVOKE_AGENT,
184731
184735
  "gen_ai.provider.name": "ur",
184732
184736
  "gen_ai.agent.name": "UR-Nexus",
184733
- "gen_ai.agent.version": "1.80.6"
184737
+ "gen_ai.agent.version": "1.80.8"
184734
184738
  };
184735
184739
  }
184736
184740
  function genAiWorkflowAttributes(workflowName, workflowRunId) {
@@ -184751,7 +184755,7 @@ function genAiWorkflowAttributes(workflowName, workflowRunId) {
184751
184755
  function startGenAiWorkflowSpan(workflowName, workflowRunId) {
184752
184756
  const attributes = genAiWorkflowAttributes(workflowName, workflowRunId);
184753
184757
  const name = typeof attributes["gen_ai.workflow.name"] === "string" ? `invoke_workflow ${attributes["gen_ai.workflow.name"]}` : GEN_AI_OPERATION_INVOKE_WORKFLOW;
184754
- return import_api10.trace.getTracer("ur-agent.gen_ai", "1.80.6").startSpan(name, { kind: import_api10.SpanKind.INTERNAL, attributes });
184758
+ return import_api10.trace.getTracer("ur-agent.gen_ai", "1.80.8").startSpan(name, { kind: import_api10.SpanKind.INTERNAL, attributes });
184755
184759
  }
184756
184760
  function endGenAiWorkflowSpan(span, options2 = {}) {
184757
184761
  try {
@@ -184789,7 +184793,7 @@ function startGenAiMemorySpan(operation, options2 = {}) {
184789
184793
  if (options2.recordCount !== undefined && Number.isInteger(options2.recordCount) && options2.recordCount >= 0) {
184790
184794
  attributes["gen_ai.memory.record.count"] = options2.recordCount;
184791
184795
  }
184792
- return import_api10.trace.getTracer("ur-agent.gen_ai", "1.80.6").startSpan(operation, { kind: import_api10.SpanKind.INTERNAL, attributes });
184796
+ return import_api10.trace.getTracer("ur-agent.gen_ai", "1.80.8").startSpan(operation, { kind: import_api10.SpanKind.INTERNAL, attributes });
184793
184797
  }
184794
184798
  function endGenAiMemorySpan(span, options2 = {}) {
184795
184799
  try {
@@ -278504,7 +278508,7 @@ function getTelemetryAttributes() {
278504
278508
  attributes["session.id"] = sessionId;
278505
278509
  }
278506
278510
  if (shouldIncludeAttribute("OTEL_METRICS_INCLUDE_VERSION")) {
278507
- attributes["app.version"] = "1.80.6";
278511
+ attributes["app.version"] = "1.80.8";
278508
278512
  }
278509
278513
  const oauthAccount = getOauthAccountInfo();
278510
278514
  if (oauthAccount) {
@@ -319495,7 +319499,7 @@ function getInstallationEnv() {
319495
319499
  return;
319496
319500
  }
319497
319501
  function getURCodeVersion() {
319498
- return "1.80.6";
319502
+ return "1.80.8";
319499
319503
  }
319500
319504
  async function getInstalledVSCodeExtensionVersion(command) {
319501
319505
  const { stdout } = await execFileNoThrow(command, ["--list-extensions", "--show-versions"], {
@@ -326865,7 +326869,7 @@ async function setupSdkMcpClients(sdkMcpConfigs, sendMcpMessage) {
326865
326869
  const client2 = new Client({
326866
326870
  name: "ur",
326867
326871
  title: "UR",
326868
- version: "1.80.6",
326872
+ version: "1.80.8",
326869
326873
  description: "UR-Nexus autonomous engineering workflow engine",
326870
326874
  websiteUrl: PRODUCT_URL
326871
326875
  }, {
@@ -327226,7 +327230,7 @@ var init_client5 = __esm(() => {
327226
327230
  const client2 = new Client({
327227
327231
  name: "ur",
327228
327232
  title: "UR",
327229
- version: "1.80.6",
327233
+ version: "1.80.8",
327230
327234
  description: "UR-Nexus autonomous engineering workflow engine",
327231
327235
  websiteUrl: PRODUCT_URL
327232
327236
  }, {
@@ -329242,6 +329246,36 @@ var init_agentToolUtils = __esm(() => {
329242
329246
  }));
329243
329247
  });
329244
329248
 
329249
+ // src/tools/AgentTool/readOnlyAgents.ts
329250
+ function isShippedReadOnlyAgentDefinition(agent) {
329251
+ return SHIPPED_READ_ONLY_AGENT_TYPES.has(agent.agentType) && agent.source === "built-in" && agent.permissionMode === "plan";
329252
+ }
329253
+ function normalizeReadOnlyResearchDelegation(input, activeAgents, isNestedAgent) {
329254
+ if (isNestedAgent || input.subagent_type !== "general-purpose" || input.name !== undefined || input.team_name !== undefined || input.isolation !== undefined || input.cwd !== undefined || typeof input.prompt !== "string" || !READ_ONLY_RESEARCH_MARKER.test(input.prompt) || !RESEARCH_INTENT_MARKER.test(input.prompt)) {
329255
+ return input;
329256
+ }
329257
+ const exploreAgent = activeAgents.find((agent) => agent.agentType === "Explore" && isShippedReadOnlyAgentDefinition(agent));
329258
+ if (!exploreAgent)
329259
+ return input;
329260
+ return { ...input, subagent_type: exploreAgent.agentType };
329261
+ }
329262
+ function shouldApplyAgentDefinitionPermissionMode(agent, parentMode, transcriptClassifierEnabled) {
329263
+ if (!agent.permissionMode)
329264
+ return false;
329265
+ if (isShippedReadOnlyAgentDefinition(agent))
329266
+ return true;
329267
+ return parentMode !== "bypassPermissions" && parentMode !== "acceptEdits" && !(transcriptClassifierEnabled && parentMode === "auto");
329268
+ }
329269
+ var SHIPPED_READ_ONLY_AGENT_TYPES, READ_ONLY_RESEARCH_MARKER, RESEARCH_INTENT_MARKER;
329270
+ var init_readOnlyAgents = __esm(() => {
329271
+ SHIPPED_READ_ONLY_AGENT_TYPES = new Set([
329272
+ "Explore",
329273
+ "Plan"
329274
+ ]);
329275
+ READ_ONLY_RESEARCH_MARKER = /\bread[\s-]?only\b|\b(?:do not|don't|must not|never)\s+(?:modify|write|edit|create|change)\s+(?:any\s+)?(?:code\s+)?files?\b|\bno\s+(?:file|workspace)\s+(?:changes|modifications)\b/i;
329276
+ RESEARCH_INTENT_MARKER = /\b(?:research|investigat\w*|explor\w*|analy[sz]\w*|audit\w*)\b/i;
329277
+ });
329278
+
329245
329279
  // src/components/AgentProgressLine.tsx
329246
329280
  function getAgentProgressStatus({
329247
329281
  isResolved,
@@ -339964,7 +339998,7 @@ async function createRuntime() {
339964
339998
  bootstrapTelemetry();
339965
339999
  const resource = defaultResource().merge(detectResources({ detectors: [envDetector] })).merge(resourceFromAttributes({
339966
340000
  [import_semantic_conventions7.ATTR_SERVICE_NAME]: "ur-agent",
339967
- [import_semantic_conventions7.ATTR_SERVICE_VERSION]: "1.80.6"
340001
+ [import_semantic_conventions7.ATTR_SERVICE_VERSION]: "1.80.8"
339968
340002
  }));
339969
340003
  const tracerProvider = exporters.traces.length > 0 ? new BasicTracerProvider({
339970
340004
  resource,
@@ -339997,11 +340031,11 @@ async function createRuntime() {
339997
340031
  setMeterProvider(meterProvider);
339998
340032
  setLoggerProvider(loggerProvider);
339999
340033
  if (meterProvider) {
340000
- const meter = meterProvider.getMeter("ur-agent", "1.80.6");
340034
+ const meter = meterProvider.getMeter("ur-agent", "1.80.8");
340001
340035
  setMeter(meter, (name, options2) => meter.createCounter(name, options2));
340002
340036
  }
340003
340037
  if (loggerProvider) {
340004
- setEventLogger(loggerProvider.getLogger("ur-agent.events", "1.80.6"));
340038
+ setEventLogger(loggerProvider.getLogger("ur-agent.events", "1.80.8"));
340005
340039
  }
340006
340040
  if (!cleanupRegistered3) {
340007
340041
  cleanupRegistered3 = true;
@@ -340663,9 +340697,9 @@ async function assertMinVersion() {
340663
340697
  if (false) {}
340664
340698
  try {
340665
340699
  const versionConfig = await getDynamicConfig_BLOCKS_ON_INIT("tengu_version_config", { minVersion: "0.0.0" });
340666
- if (versionConfig.minVersion && lt("1.80.6", versionConfig.minVersion)) {
340700
+ if (versionConfig.minVersion && lt("1.80.8", versionConfig.minVersion)) {
340667
340701
  console.error(`
340668
- It looks like your version of UR (${"1.80.6"}) needs an update.
340702
+ It looks like your version of UR (${"1.80.8"}) needs an update.
340669
340703
  A newer version (${versionConfig.minVersion} or higher) is required to continue.
340670
340704
 
340671
340705
  To update, please run:
@@ -340881,7 +340915,7 @@ async function installGlobalPackage(specificVersion) {
340881
340915
  logError2(new AutoUpdaterError("Another process is currently installing an update"));
340882
340916
  logEvent("tengu_auto_updater_lock_contention", {
340883
340917
  pid: process.pid,
340884
- currentVersion: "1.80.6"
340918
+ currentVersion: "1.80.8"
340885
340919
  });
340886
340920
  return "in_progress";
340887
340921
  }
@@ -340890,7 +340924,7 @@ async function installGlobalPackage(specificVersion) {
340890
340924
  if (!env2.isRunningWithBun() && env2.isNpmFromWindowsPath()) {
340891
340925
  logError2(new Error("Windows NPM detected in WSL environment"));
340892
340926
  logEvent("tengu_auto_updater_windows_npm_in_wsl", {
340893
- currentVersion: "1.80.6"
340927
+ currentVersion: "1.80.8"
340894
340928
  });
340895
340929
  console.error(`
340896
340930
  Error: Windows NPM detected in WSL
@@ -341425,7 +341459,7 @@ function detectLinuxGlobPatternWarnings() {
341425
341459
  }
341426
341460
  async function getDoctorDiagnostic() {
341427
341461
  const installationType = await getCurrentInstallationType();
341428
- const version2 = typeof MACRO !== "undefined" ? "1.80.6" : "unknown";
341462
+ const version2 = typeof MACRO !== "undefined" ? "1.80.8" : "unknown";
341429
341463
  const installationPath = await getInstallationPath();
341430
341464
  const invokedBinary = getInvokedBinary();
341431
341465
  const multipleInstallations = await detectMultipleInstallations();
@@ -342360,8 +342394,8 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
342360
342394
  const maxVersion = await getMaxVersion();
342361
342395
  if (maxVersion && gt(version2, maxVersion)) {
342362
342396
  logForDebugging(`Native installer: maxVersion ${maxVersion} is set, capping update from ${version2} to ${maxVersion}`);
342363
- if (gte("1.80.6", maxVersion)) {
342364
- logForDebugging(`Native installer: current version ${"1.80.6"} is already at or above maxVersion ${maxVersion}, skipping update`);
342397
+ if (gte("1.80.8", maxVersion)) {
342398
+ logForDebugging(`Native installer: current version ${"1.80.8"} is already at or above maxVersion ${maxVersion}, skipping update`);
342365
342399
  logEvent("tengu_native_update_skipped_max_version", {
342366
342400
  latency_ms: Date.now() - startTime,
342367
342401
  max_version: maxVersion,
@@ -342372,7 +342406,7 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
342372
342406
  version2 = maxVersion;
342373
342407
  }
342374
342408
  }
342375
- if (!forceReinstall && version2 === "1.80.6" && await versionIsAvailable(version2) && await isPossibleURBinary(executablePath)) {
342409
+ if (!forceReinstall && version2 === "1.80.8" && await versionIsAvailable(version2) && await isPossibleURBinary(executablePath)) {
342376
342410
  logForDebugging(`Found ${version2} at ${executablePath}, skipping install`);
342377
342411
  logEvent("tengu_native_update_complete", {
342378
342412
  latency_ms: Date.now() - startTime,
@@ -363462,7 +363496,7 @@ async function* runAgent({
363462
363496
  const agentGetAppState = () => {
363463
363497
  const state = toolUseContext.getAppState();
363464
363498
  let toolPermissionContext = state.toolPermissionContext;
363465
- if (agentPermissionMode && state.toolPermissionContext.mode !== "bypassPermissions" && state.toolPermissionContext.mode !== "acceptEdits" && true) {
363499
+ if (agentPermissionMode && shouldApplyAgentDefinitionPermissionMode(agentDefinition, state.toolPermissionContext.mode, false)) {
363466
363500
  toolPermissionContext = {
363467
363501
  ...toolPermissionContext,
363468
363502
  mode: agentPermissionMode
@@ -363755,6 +363789,7 @@ var init_runAgent = __esm(() => {
363755
363789
  init_uuid();
363756
363790
  init_agentToolUtils();
363757
363791
  init_loadAgentsDir();
363792
+ init_readOnlyAgents();
363758
363793
  });
363759
363794
 
363760
363795
  // src/services/AgentSummary/agentSummary.ts
@@ -396228,7 +396263,7 @@ function checkTaskListGate(input) {
396228
396263
  return { allowed: true };
396229
396264
  if (input.isPlanningArtifact === true)
396230
396265
  return { allowed: true };
396231
- if (input.isReadOnlyPlanningDelegation === true)
396266
+ if (input.isReadOnlyBuiltInDelegation === true)
396232
396267
  return { allowed: true };
396233
396268
  const isMutating = input.isMutating ?? isMutatingTool2(input.toolName);
396234
396269
  if (!isMutating)
@@ -406681,7 +406716,7 @@ async function getPrompt9(agentDefinitions, isCoordinator, allowedAgentTypes) {
406681
406716
  ## When to fork
406682
406717
 
406683
406718
  Fork yourself (omit \`subagent_type\`) when the intermediate tool output isn't worth keeping in your context. The criterion is qualitative \u2014 "will I need this output again" \u2014 not task size.
406684
- - **Research**: fork open-ended questions. If research can be broken into independent questions, launch parallel forks in one message. A fork beats a fresh subagent for this \u2014 it inherits context and shares your cache.
406719
+ - **Research after tasks exist**: fork open-ended questions when inherited context is valuable. Before an actionable task exists, use the shipped \`Explore\` agent instead; a fork or general-purpose agent is write-capable and will be task-gated. If research can be broken into independent questions, launch parallel \`Explore\` agents in one message.
406685
406720
  - **Implementation**: fork only a bounded branch with explicit file scope. Parallel implementation forks must use isolated worktrees based on the exact clean starting revision; otherwise keep shared-checkout writers sequential. Do research before jumping to implementation.
406686
406721
 
406687
406722
  Forks are cheap because they share your prompt cache. Don't set \`model\` on a fork \u2014 a different model can't reuse the parent's cache. Pass a short \`name\` (one or two words, lowercase) so the user can see the fork in the teams panel and steer it mid-run.
@@ -413027,7 +413062,7 @@ function isAnyTracingEnabled() {
413027
413062
  return isTelemetryEnabled() || isEnhancedTelemetryEnabled() || isBetaTracingEnabled();
413028
413063
  }
413029
413064
  function getTracer() {
413030
- return import_api39.trace.getTracer("ur-agent.gen_ai", "1.80.6");
413065
+ return import_api39.trace.getTracer("ur-agent.gen_ai", "1.80.8");
413031
413066
  }
413032
413067
  function createSpanAttributes(spanType, customAttributes = {}) {
413033
413068
  const baseAttributes = getTelemetryAttributes();
@@ -414482,15 +414517,15 @@ function isCurrentPlanFileMutation(toolName, input, context5) {
414482
414517
  return false;
414483
414518
  }
414484
414519
  }
414485
- function isReadOnlyPlanningDelegation(toolName, input, context5) {
414486
- if (context5.agentId || context5.getAppState().toolPermissionContext.mode !== "plan" || toolName !== AGENT_TOOL_NAME && toolName !== LEGACY_AGENT_TOOL_NAME || !input || typeof input !== "object" || Array.isArray(input)) {
414520
+ function isReadOnlyBuiltInDelegation(toolName, input, context5) {
414521
+ if (context5.agentId || toolName !== AGENT_TOOL_NAME && toolName !== LEGACY_AGENT_TOOL_NAME || !input || typeof input !== "object" || Array.isArray(input)) {
414487
414522
  return false;
414488
414523
  }
414489
414524
  const delegation = input;
414490
- if (typeof delegation.subagent_type !== "string" || !READ_ONLY_PLANNING_AGENT_TYPES.has(delegation.subagent_type) || delegation.name !== undefined || delegation.team_name !== undefined || delegation.isolation !== undefined) {
414525
+ if (typeof delegation.subagent_type !== "string" || delegation.name !== undefined || delegation.team_name !== undefined || delegation.isolation !== undefined) {
414491
414526
  return false;
414492
414527
  }
414493
- return context5.options.agentDefinitions.activeAgents.some((agent) => agent.agentType === delegation.subagent_type && agent.source === "built-in" && agent.permissionMode === "plan");
414528
+ return context5.options.agentDefinitions.activeAgents.some((agent) => agent.agentType === delegation.subagent_type && isShippedReadOnlyAgentDefinition(agent));
414494
414529
  }
414495
414530
  function getStopHookInfo(attachment) {
414496
414531
  if (typeof attachment !== "object" || attachment === null || !("command" in attachment) || typeof attachment.command !== "string" || !("durationMs" in attachment) || typeof attachment.durationMs !== "number") {
@@ -414604,13 +414639,7 @@ function getMcpServerBaseUrlFromToolName(toolName, mcpClients) {
414604
414639
  }
414605
414640
  async function* runToolUse(toolUse, assistantMessage, canUseTool, toolUseContext) {
414606
414641
  const toolName = toolUse.name;
414607
- let tool = findToolByName(toolUseContext.options.tools, toolName);
414608
- if (!tool) {
414609
- const fallbackTool = findToolByName(getAllBaseTools(), toolName);
414610
- if (fallbackTool && fallbackTool.aliases?.includes(toolName)) {
414611
- tool = fallbackTool;
414612
- }
414613
- }
414642
+ const tool = findToolByName(toolUseContext.options.tools, toolName);
414614
414643
  const messageId = assistantMessage.message?.id;
414615
414644
  if (typeof messageId !== "string" || messageId.length === 0) {
414616
414645
  throw new Error(`Cannot execute tool_use ${toolUse.id}: assistant message has no id`);
@@ -414620,7 +414649,7 @@ async function* runToolUse(toolUse, assistantMessage, canUseTool, toolUseContext
414620
414649
  const mcpServerBaseUrl = getMcpServerBaseUrlFromToolName(toolName, toolUseContext.options.mcpClients);
414621
414650
  if (!tool) {
414622
414651
  const callSig = callSignature(toolName, toolUse.input, repeatedFailureScope(toolUseContext, messageId));
414623
- const repeat2 = checkRepeatedFailure(callSig);
414652
+ const repeat2 = checkRepeatedFailure(callSig, UNKNOWN_TOOL_REPEAT_POLICY);
414624
414653
  if (repeat2.action === "abort") {
414625
414654
  throw new RepeatedToolFailureAbort(`Repeated tool failure: ${repeat2.reason}`);
414626
414655
  }
@@ -414662,17 +414691,18 @@ async function* runToolUse(toolUse, assistantMessage, canUseTool, toolUseContext
414662
414691
  },
414663
414692
  ...mcpToolDetailsForAnalytics(toolName, mcpServerType, mcpServerBaseUrl)
414664
414693
  });
414694
+ const unavailableMessage = `Tool "${toolName}" is not available in this agent's active tool profile. Do not retry this tool unchanged. Continue with an available tool, or return the useful partial result so the parent agent can proceed.`;
414665
414695
  yield {
414666
414696
  message: createUserMessage({
414667
414697
  content: [
414668
414698
  {
414669
414699
  type: "tool_result",
414670
- content: `<tool_use_error>Error: No such tool available: ${toolName}</tool_use_error>`,
414700
+ content: `<tool_use_error>UnavailableTool: ${unavailableMessage}</tool_use_error>`,
414671
414701
  is_error: true,
414672
414702
  tool_use_id: toolUse.id
414673
414703
  }
414674
414704
  ],
414675
- toolUseResult: `Error: No such tool available: ${toolName}`,
414705
+ toolUseResult: `UnavailableTool: ${unavailableMessage}`,
414676
414706
  sourceToolAssistantUUID: assistantMessage.uuid
414677
414707
  })
414678
414708
  };
@@ -414824,6 +414854,16 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContex
414824
414854
  }
414825
414855
  }
414826
414856
  }
414857
+ if (parsedInput.success && (tool.name === AGENT_TOOL_NAME || tool.name === LEGACY_AGENT_TOOL_NAME)) {
414858
+ const normalizedDelegation = normalizeReadOnlyResearchDelegation(parsedInput.data, toolUseContext.options.agentDefinitions.activeAgents, Boolean(toolUseContext.agentId));
414859
+ if (normalizedDelegation !== parsedInput.data) {
414860
+ input = normalizedDelegation;
414861
+ parsedInput = tool.inputSchema.safeParse(input);
414862
+ logEvent("tengu_agent_read_only_research_normalized", {
414863
+ toolName: sanitizeToolNameForAnalytics(tool.name)
414864
+ });
414865
+ }
414866
+ }
414827
414867
  let callSig = callSignature(tool.name, input, repeatedFailureScope(toolUseContext, messageId));
414828
414868
  const repeat2 = checkRepeatedFailure(callSig);
414829
414869
  if (repeat2.action !== "allow") {
@@ -414957,7 +414997,7 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContex
414957
414997
  requiresTaskList: taskListRun?.requiresTaskList,
414958
414998
  requirementReason: taskListRun?.requirementReason,
414959
414999
  isPlanningArtifact: isCurrentPlanFileMutation(tool.name, parsedInput.data, toolUseContext),
414960
- isReadOnlyPlanningDelegation: isReadOnlyPlanningDelegation(tool.name, parsedInput.data, toolUseContext),
415000
+ isReadOnlyBuiltInDelegation: isReadOnlyBuiltInDelegation(tool.name, parsedInput.data, toolUseContext),
414961
415001
  taskListWriterAvailable: toolUseContext.options.tools.some((candidate) => candidate.name === "TaskCreate")
414962
415002
  });
414963
415003
  if (gate.allowed === false) {
@@ -415319,7 +415359,7 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContex
415319
415359
  requiresTaskList: taskListRun?.requiresTaskList,
415320
415360
  requirementReason: taskListRun?.requirementReason,
415321
415361
  isPlanningArtifact: isCurrentPlanFileMutation(tool.name, finalParsedInput.data, toolUseContext),
415322
- isReadOnlyPlanningDelegation: isReadOnlyPlanningDelegation(tool.name, finalParsedInput.data, toolUseContext),
415362
+ isReadOnlyBuiltInDelegation: isReadOnlyBuiltInDelegation(tool.name, finalParsedInput.data, toolUseContext),
415323
415363
  taskListWriterAvailable: toolUseContext.options.tools.some((candidate) => candidate.name === "TaskCreate")
415324
415364
  });
415325
415365
  if (finalGate.allowed === false) {
@@ -415729,7 +415769,7 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContex
415729
415769
  }
415730
415770
  }
415731
415771
  }
415732
- var READ_ONLY_PLANNING_AGENT_TYPES, HOOK_TIMING_DISPLAY_THRESHOLD_MS2 = 500, SLOW_PHASE_LOG_THRESHOLD_MS = 2000;
415772
+ var UNKNOWN_TOOL_REPEAT_POLICY, HOOK_TIMING_DISPLAY_THRESHOLD_MS2 = 500, SLOW_PHASE_LOG_THRESHOLD_MS = 2000;
415733
415773
  var init_toolExecution = __esm(() => {
415734
415774
  init_analytics();
415735
415775
  init_metadata();
@@ -415741,11 +415781,11 @@ var init_toolExecution = __esm(() => {
415741
415781
  init_prompt();
415742
415782
  init_bashPermissions();
415743
415783
  init_constants2();
415784
+ init_readOnlyAgents();
415744
415785
  init_prompt3();
415745
415786
  init_prompt4();
415746
415787
  init_gitOperationTracking();
415747
415788
  init_prompt8();
415748
- init_tools2();
415749
415789
  init_attachments2();
415750
415790
  init_debug();
415751
415791
  init_errors();
@@ -415771,7 +415811,11 @@ var init_toolExecution = __esm(() => {
415771
415811
  init_mcpStringUtils();
415772
415812
  init_utils3();
415773
415813
  init_toolHooks();
415774
- READ_ONLY_PLANNING_AGENT_TYPES = new Set(["Explore", "Plan"]);
415814
+ UNKNOWN_TOOL_REPEAT_POLICY = {
415815
+ enabled: true,
415816
+ limit: 1,
415817
+ abortAfter: 3
415818
+ };
415775
415819
  });
415776
415820
 
415777
415821
  // src/services/tools/StreamingToolExecutor.ts
@@ -443147,7 +443191,7 @@ function Feedback({
443147
443191
  platform: env2.platform,
443148
443192
  gitRepo: envInfo.isGit,
443149
443193
  terminal: env2.terminal,
443150
- version: "1.80.6",
443194
+ version: "1.80.8",
443151
443195
  transcript: normalizeMessagesForAPI(messages),
443152
443196
  errors: sanitizedErrors,
443153
443197
  lastApiRequest: getLastAPIRequest(),
@@ -443339,7 +443383,7 @@ function Feedback({
443339
443383
  ", ",
443340
443384
  env2.terminal,
443341
443385
  ", v",
443342
- "1.80.6"
443386
+ "1.80.8"
443343
443387
  ]
443344
443388
  }, undefined, true, undefined, this)
443345
443389
  ]
@@ -443445,7 +443489,7 @@ ${sanitizedDescription}
443445
443489
  ` + `**Environment Info**
443446
443490
  ` + `- Platform: ${env2.platform}
443447
443491
  ` + `- Terminal: ${env2.terminal}
443448
- ` + `- Version: ${"1.80.6"}
443492
+ ` + `- Version: ${"1.80.8"}
443449
443493
  ` + `- Feedback ID: ${feedbackId}
443450
443494
  ` + `
443451
443495
  **Errors**
@@ -446555,7 +446599,7 @@ function buildPrimarySection() {
446555
446599
  }, undefined, false, undefined, this);
446556
446600
  return [{
446557
446601
  label: "Version",
446558
- value: "1.80.6"
446602
+ value: "1.80.8"
446559
446603
  }, {
446560
446604
  label: "Session name",
446561
446605
  value: nameValue
@@ -449937,7 +449981,7 @@ function Config({
449937
449981
  }
449938
449982
  }, undefined, false, undefined, this)
449939
449983
  }, undefined, false, undefined, this) : showSubmenu === "ChannelDowngrade" ? /* @__PURE__ */ jsx_dev_runtime179.jsxDEV(ChannelDowngradeDialog, {
449940
- currentVersion: "1.80.6",
449984
+ currentVersion: "1.80.8",
449941
449985
  onChoice: (choice) => {
449942
449986
  setShowSubmenu(null);
449943
449987
  setTabsHidden(false);
@@ -449949,7 +449993,7 @@ function Config({
449949
449993
  autoUpdatesChannel: "stable"
449950
449994
  };
449951
449995
  if (choice === "stay") {
449952
- newSettings.minimumVersion = "1.80.6";
449996
+ newSettings.minimumVersion = "1.80.8";
449953
449997
  }
449954
449998
  updateSettingsForSource("userSettings", newSettings);
449955
449999
  setSettingsData((prev_27) => ({
@@ -458258,7 +458302,7 @@ function HelpV2(t0) {
458258
458302
  let t6;
458259
458303
  if ($2[31] !== tabs) {
458260
458304
  t6 = /* @__PURE__ */ jsx_dev_runtime206.jsxDEV(Tabs, {
458261
- title: `UR v${"1.80.6"}`,
458305
+ title: `UR v${"1.80.8"}`,
458262
458306
  color: "professionalBlue",
458263
458307
  defaultTab: "general",
458264
458308
  children: tabs
@@ -459191,7 +459235,7 @@ function buildToolUseContext(tools, readFileStateCache, toolPermissionContext, a
459191
459235
  async function handleInitialize(options2) {
459192
459236
  return {
459193
459237
  name: "UR",
459194
- version: "1.80.6",
459238
+ version: "1.80.8",
459195
459239
  protocolVersion: "0.1.0",
459196
459240
  workspaceRoot: options2.cwd,
459197
459241
  capabilities: {
@@ -476299,7 +476343,7 @@ function getAllReleaseNotes(changelogContent = getStoredChangelogFromMemory()) {
476299
476343
  return [];
476300
476344
  }
476301
476345
  }
476302
- async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.80.6") {
476346
+ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.80.8") {
476303
476347
  if (process.env.USER_TYPE === "ant") {
476304
476348
  const changelog = "";
476305
476349
  if (changelog) {
@@ -476326,7 +476370,7 @@ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.80.6")
476326
476370
  releaseNotes
476327
476371
  };
476328
476372
  }
476329
- function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.80.6") {
476373
+ function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.80.8") {
476330
476374
  if (process.env.USER_TYPE === "ant") {
476331
476375
  const changelog = "";
476332
476376
  if (changelog) {
@@ -479231,7 +479275,7 @@ function getRecentActivitySync() {
479231
479275
  return cachedActivity;
479232
479276
  }
479233
479277
  function getLogoDisplayData() {
479234
- const version2 = process.env.DEMO_VERSION ?? "1.80.6";
479278
+ const version2 = process.env.DEMO_VERSION ?? "1.80.8";
479235
479279
  const serverUrl = getDirectConnectServerUrl();
479236
479280
  const displayPath = process.env.DEMO_VERSION ? "/code/ur" : getDisplayPath(getCwd());
479237
479281
  const cwd2 = serverUrl ? `${displayPath} in ${serverUrl.replace(/^https?:\/\//, "")}` : displayPath;
@@ -480099,7 +480143,7 @@ function LogoV2() {
480099
480143
  if ($2[2] === Symbol.for("react.memo_cache_sentinel")) {
480100
480144
  t2 = () => {
480101
480145
  const currentConfig = getGlobalConfig();
480102
- if (currentConfig.lastReleaseNotesSeen === "1.80.6") {
480146
+ if (currentConfig.lastReleaseNotesSeen === "1.80.8") {
480103
480147
  return;
480104
480148
  }
480105
480149
  saveGlobalConfig(_temp325);
@@ -480784,12 +480828,12 @@ function LogoV2() {
480784
480828
  return t41;
480785
480829
  }
480786
480830
  function _temp325(current) {
480787
- if (current.lastReleaseNotesSeen === "1.80.6") {
480831
+ if (current.lastReleaseNotesSeen === "1.80.8") {
480788
480832
  return current;
480789
480833
  }
480790
480834
  return {
480791
480835
  ...current,
480792
- lastReleaseNotesSeen: "1.80.6"
480836
+ lastReleaseNotesSeen: "1.80.8"
480793
480837
  };
480794
480838
  }
480795
480839
  function _temp241(s_0) {
@@ -496881,7 +496925,7 @@ function compileAgenticCiWorkflow(specName = "default", options2 = {}) {
496881
496925
  if (spec.name !== specName) {
496882
496926
  throw new Error("Agentic CI workflow spec name does not match");
496883
496927
  }
496884
- const packageVersion = options2.packageVersion ?? (typeof MACRO !== "undefined" ? "1.80.6" : "1.80.6");
496928
+ const packageVersion = options2.packageVersion ?? (typeof MACRO !== "undefined" ? "1.80.8" : "1.80.8");
496885
496929
  if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(packageVersion)) {
496886
496930
  throw new Error("invalid ur-agent package version");
496887
496931
  }
@@ -497874,7 +497918,7 @@ runner; \`ur trigger\` is the inbound parser that decides what to run.
497874
497918
  path: ".github/workflows/ur.yml",
497875
497919
  root: "project",
497876
497920
  content: compileAgenticCiWorkflow("default", {
497877
- packageVersion: typeof MACRO !== "undefined" ? "1.80.6" : "1.80.6"
497921
+ packageVersion: typeof MACRO !== "undefined" ? "1.80.8" : "1.80.8"
497878
497922
  })
497879
497923
  },
497880
497924
  {
@@ -497937,7 +497981,7 @@ function value(tokens, flag) {
497937
497981
  return index2 >= 0 ? tokens[index2 + 1] : undefined;
497938
497982
  }
497939
497983
  function cliVersion() {
497940
- return typeof MACRO !== "undefined" ? "1.80.6" : "1.80.6";
497984
+ return typeof MACRO !== "undefined" ? "1.80.8" : "1.80.8";
497941
497985
  }
497942
497986
  function workflowPath(cwd2) {
497943
497987
  return join168(cwd2, ".github", "workflows", "ur-agentic-ci.yml");
@@ -503793,7 +503837,7 @@ function createAcpStdioApp(deps) {
503793
503837
  }
503794
503838
  },
503795
503839
  authMethods: [],
503796
- agentInfo: { name: "UR-Nexus", version: "1.80.6" }
503840
+ agentInfo: { name: "UR-Nexus", version: "1.80.8" }
503797
503841
  })).onRequest("authenticate", () => ({})).onRequest("session/new", async (context6) => {
503798
503842
  const result = runtime2.newSession(context6.params.cwd, context6.params.mcpServers, context6.params.additionalDirectories);
503799
503843
  await runtime2.announce({
@@ -503890,7 +503934,7 @@ function createAcpStdioAgent(deps) {
503890
503934
  }
503891
503935
  },
503892
503936
  authMethods: [],
503893
- agentInfo: { name: "UR-Nexus", version: "1.80.6" }
503937
+ agentInfo: { name: "UR-Nexus", version: "1.80.8" }
503894
503938
  });
503895
503939
  return;
503896
503940
  case "authenticate":
@@ -715116,7 +715160,7 @@ async function captureMemoryDiagnostics(trigger2, dumpNumber = 0) {
715116
715160
  smapsRollup,
715117
715161
  platform: process.platform,
715118
715162
  nodeVersion: process.version,
715119
- ccVersion: "1.80.6"
715163
+ ccVersion: "1.80.8"
715120
715164
  };
715121
715165
  }
715122
715166
  async function performHeapDump(trigger2 = "manual", dumpNumber = 0) {
@@ -715705,7 +715749,7 @@ var init_bridge_kick = __esm(() => {
715705
715749
  var call154 = async () => {
715706
715750
  return {
715707
715751
  type: "text",
715708
- value: "1.80.6"
715752
+ value: "1.80.8"
715709
715753
  };
715710
715754
  }, version2, version_default;
715711
715755
  var init_version = __esm(() => {
@@ -726948,7 +726992,7 @@ function generateHtmlReport(data, insights) {
726948
726992
  </html>`;
726949
726993
  }
726950
726994
  function buildExportData(data, insights, facets, remoteStats) {
726951
- const version3 = typeof MACRO !== "undefined" ? "1.80.6" : "unknown";
726995
+ const version3 = typeof MACRO !== "undefined" ? "1.80.8" : "unknown";
726952
726996
  const remote_hosts_collected = remoteStats?.hosts.filter((h2) => h2.sessionCount > 0).map((h2) => h2.name);
726953
726997
  const facets_summary = {
726954
726998
  total: facets.size,
@@ -731261,7 +731305,7 @@ var init_sessionStorage = __esm(() => {
731261
731305
  init_settings2();
731262
731306
  init_slowOperations();
731263
731307
  init_uuid();
731264
- VERSION7 = typeof MACRO !== "undefined" ? "1.80.6" : "unknown";
731308
+ VERSION7 = typeof MACRO !== "undefined" ? "1.80.8" : "unknown";
731265
731309
  MAX_TOMBSTONE_REWRITE_BYTES = 50 * 1024 * 1024;
731266
731310
  SKIP_FIRST_PROMPT_PATTERN = /^(?:\s*<[a-z][\w-]*[\s>]|\[Request interrupted by user[^\]]*\])/;
731267
731311
  EPHEMERAL_PROGRESS_TYPES = new Set([
@@ -732476,7 +732520,7 @@ var init_filesystem = __esm(() => {
732476
732520
  });
732477
732521
  getBundledSkillsRoot = memoize_default(function getBundledSkillsRoot2() {
732478
732522
  const nonce = randomBytes24(16).toString("hex");
732479
- return join243(getURTempDir(), "bundled-skills", "1.80.6", nonce);
732523
+ return join243(getURTempDir(), "bundled-skills", "1.80.8", nonce);
732480
732524
  });
732481
732525
  getResolvedWorkingDirPaths = memoize_default(getPathsForPermissionCheck);
732482
732526
  });
@@ -738086,6 +738130,7 @@ function getOllamaToolDisciplineSection() {
738086
738130
  return null;
738087
738131
  const items = [
738088
738132
  `Use the native structured tool-call interface; never substitute prose, fenced code, XML, or printed arguments for a call. Only use a text fallback when the runtime explicitly says native tools are unavailable and supplies the exact fallback format.`,
738133
+ `Call only tools exposed in the active tool list. If a tool result says a tool is unavailable, do not retry it unchanged: use an available alternative or continue with the useful partial result.`,
738089
738134
  `Use ${FILE_WRITE_TOOL_NAME} or ${FILE_EDIT_TOOL_NAME} for file changes. Batch independent calls in one turn (maximum 8); keep read\u2192decide\u2192write and other dependencies sequential.`,
738090
738135
  `Treat each call as pending until its matching result arrives. Observe that result before continuing, and never claim a file change, command, test, or other action succeeded without a successful result.`,
738091
738136
  `Never emit an empty turn: provide a real tool call, useful user-facing text, or both.`
@@ -738095,7 +738140,7 @@ function getOllamaToolDisciplineSection() {
738095
738140
  }
738096
738141
  function getAgentToolSection() {
738097
738142
  const launch = isForkSubagentEnabled() ? `Calling ${AGENT_TOOL_NAME} without a subagent_type creates a fork, which runs in the background and keeps its raw tool output out of your context. **If you ARE the fork**, execute your bounded assignment directly; do not re-delegate.` : `Use ${AGENT_TOOL_NAME} with the specialized agent whose description best matches each bounded assignment.`;
738098
- return `${launch} For a large request, first create a bounded task list, then delegate at most one ready independent branch per agent. Launch independent read-only research, audits, or exploration together. Shared-checkout writers, unknown scopes, dependencies, and overlapping file targets must run sequentially. Parallel writers require separate worktrees based on the exact clean starting revision; if the current required state is dirty or unsnapshotted, keep those writers serial in the shared checkout. Keep tiny dependent steps with the parent when delegation overhead is larger than the work. The parent owns task status, integration, and final verification: do not duplicate delegated work, do not mark a delegated task complete from a launch acknowledgement, and do not finish until the returned result and acceptance evidence have been checked.`;
738143
+ return `${launch} For a large request, first create a bounded task list, then delegate at most one ready independent branch per agent. Before that list exists, read-only research, audits, and exploration MUST use subagent_type="Explore" (or "Plan" for planning); never label a read-only worker general-purpose. Every custom, general-purpose, write-capable, nested, team, or worktree delegation requires a ready parent task. Launch independent read-only research, audits, or exploration together. Shared-checkout writers, unknown scopes, dependencies, and overlapping file targets must run sequentially. Parallel writers require separate worktrees based on the exact clean starting revision; if the current required state is dirty or unsnapshotted, keep those writers serial in the shared checkout. Keep tiny dependent steps with the parent when delegation overhead is larger than the work. The parent owns task status, integration, and final verification: do not duplicate delegated work, do not mark a delegated task complete from a launch acknowledgement, and do not finish until the returned result and acceptance evidence have been checked.`;
738099
738144
  }
738100
738145
  function getDiscoverSkillsGuidance() {
738101
738146
  if (false) {}
@@ -738865,7 +738910,7 @@ function computeFingerprint(messageText2, version3) {
738865
738910
  }
738866
738911
  function computeFingerprintFromMessages(messages) {
738867
738912
  const firstMessageText = extractFirstMessageText(messages);
738868
- return computeFingerprint(firstMessageText, "1.80.6");
738913
+ return computeFingerprint(firstMessageText, "1.80.8");
738869
738914
  }
738870
738915
  var FINGERPRINT_SALT = "59cf53e54c78";
738871
738916
  var init_fingerprint = () => {};
@@ -740790,7 +740835,7 @@ async function sideQuery(opts) {
740790
740835
  betas.push(STRUCTURED_OUTPUTS_BETA_HEADER);
740791
740836
  }
740792
740837
  const messageText2 = extractFirstUserMessageText(messages);
740793
- const fingerprint2 = computeFingerprint(messageText2, "1.80.6");
740838
+ const fingerprint2 = computeFingerprint(messageText2, "1.80.8");
740794
740839
  const attributionHeader = getAttributionHeader(fingerprint2);
740795
740840
  const systemBlocks = [
740796
740841
  attributionHeader ? { type: "text", text: attributionHeader } : null,
@@ -745624,7 +745669,7 @@ function buildSystemInitMessage(inputs) {
745624
745669
  slash_commands: inputs.commands.filter((c4) => c4.userInvocable !== false).map((c4) => c4.name),
745625
745670
  apiKeySource: getURHQApiKeyWithSource().source,
745626
745671
  betas: getSdkBetas(),
745627
- ur_version: "1.80.6",
745672
+ ur_version: "1.80.8",
745628
745673
  output_style: outputStyle,
745629
745674
  agents: inputs.agents.map((agent2) => agent2.agentType),
745630
745675
  skills: inputs.skills.filter((s) => s.userInvocable !== false).map((skill2) => skill2.name),
@@ -759460,7 +759505,7 @@ var init_useVoiceEnabled = __esm(() => {
759460
759505
  function getSemverPart(version3) {
759461
759506
  return `${import_semver13.major(version3, { loose: true })}.${import_semver13.minor(version3, { loose: true })}.${import_semver13.patch(version3, { loose: true })}`;
759462
759507
  }
759463
- function useUpdateNotification(updatedVersion, initialVersion = "1.80.6") {
759508
+ function useUpdateNotification(updatedVersion, initialVersion = "1.80.8") {
759464
759509
  const [lastNotifiedSemver, setLastNotifiedSemver] = import_react225.useState(() => getSemverPart(initialVersion));
759465
759510
  if (!updatedVersion) {
759466
759511
  return null;
@@ -759509,7 +759554,7 @@ function AutoUpdater({
759509
759554
  return;
759510
759555
  }
759511
759556
  if (false) {}
759512
- const currentVersion = "1.80.6";
759557
+ const currentVersion = "1.80.8";
759513
759558
  const channel = getInitialSettings()?.autoUpdatesChannel ?? "latest";
759514
759559
  let latestVersion = await getLatestVersion(channel);
759515
759560
  const isDisabled = isAutoUpdaterDisabled();
@@ -759738,12 +759783,12 @@ function NativeAutoUpdater({
759738
759783
  logEvent("tengu_native_auto_updater_start", {});
759739
759784
  try {
759740
759785
  const maxVersion = await getMaxVersion();
759741
- if (maxVersion && gt("1.80.6", maxVersion)) {
759786
+ if (maxVersion && gt("1.80.8", maxVersion)) {
759742
759787
  const msg = await getMaxVersionMessage();
759743
759788
  setMaxVersionIssue(msg ?? "affects your version");
759744
759789
  }
759745
759790
  const result = await installLatest(channel);
759746
- const currentVersion = "1.80.6";
759791
+ const currentVersion = "1.80.8";
759747
759792
  const latencyMs = Date.now() - startTime;
759748
759793
  if (result.lockFailed) {
759749
759794
  logEvent("tengu_native_auto_updater_lock_contention", {
@@ -759880,17 +759925,17 @@ function PackageManagerAutoUpdater(t0) {
759880
759925
  const maxVersion = await getMaxVersion();
759881
759926
  if (maxVersion && latest && gt(latest, maxVersion)) {
759882
759927
  logForDebugging(`PackageManagerAutoUpdater: maxVersion ${maxVersion} is set, capping update from ${latest} to ${maxVersion}`);
759883
- if (gte("1.80.6", maxVersion)) {
759884
- logForDebugging(`PackageManagerAutoUpdater: current version ${"1.80.6"} is already at or above maxVersion ${maxVersion}, skipping update`);
759928
+ if (gte("1.80.8", maxVersion)) {
759929
+ logForDebugging(`PackageManagerAutoUpdater: current version ${"1.80.8"} is already at or above maxVersion ${maxVersion}, skipping update`);
759885
759930
  setUpdateAvailable(false);
759886
759931
  return;
759887
759932
  }
759888
759933
  latest = maxVersion;
759889
759934
  }
759890
- const hasUpdate = latest && !gte("1.80.6", latest) && !shouldSkipVersion(latest);
759935
+ const hasUpdate = latest && !gte("1.80.8", latest) && !shouldSkipVersion(latest);
759891
759936
  setUpdateAvailable(!!hasUpdate);
759892
759937
  if (hasUpdate) {
759893
- logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.80.6"} -> ${latest}`);
759938
+ logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.80.8"} -> ${latest}`);
759894
759939
  }
759895
759940
  };
759896
759941
  $2[0] = t1;
@@ -759924,7 +759969,7 @@ function PackageManagerAutoUpdater(t0) {
759924
759969
  wrap: "truncate",
759925
759970
  children: [
759926
759971
  "currentVersion: ",
759927
- "1.80.6"
759972
+ "1.80.8"
759928
759973
  ]
759929
759974
  }, undefined, true, undefined, this);
759930
759975
  $2[3] = verbose;
@@ -770777,7 +770822,7 @@ function buildStatusLineCommandInput(permissionMode, exceeds200kTokens, settings
770777
770822
  project_dir: getOriginalCwd(),
770778
770823
  added_dirs: addedDirs
770779
770824
  },
770780
- version: "1.80.6",
770825
+ version: "1.80.8",
770781
770826
  output_style: {
770782
770827
  name: outputStyleName
770783
770828
  },
@@ -770912,7 +770957,7 @@ function StatusLineInner({
770912
770957
  const attention = customStatusError ?? taskAttention;
770913
770958
  const terminalSize = React133.useContext(TerminalSizeContext);
770914
770959
  const defaultStatusLineText = buildDefaultStatusBar({
770915
- version: "1.80.6",
770960
+ version: "1.80.8",
770916
770961
  providerLabel: providerRuntime.providerLabel,
770917
770962
  authMode: providerRuntime.authLabel,
770918
770963
  model: renderModelName(mainLoopModel) || providerRuntime.model || "",
@@ -783167,7 +783212,7 @@ async function submitTranscriptShare(messages, trigger2, appearanceId) {
783167
783212
  } catch {}
783168
783213
  const data = {
783169
783214
  trigger: trigger2,
783170
- version: "1.80.6",
783215
+ version: "1.80.8",
783171
783216
  platform: process.platform,
783172
783217
  transcript,
783173
783218
  subagentTranscripts: Object.keys(subagentTranscripts).length > 0 ? subagentTranscripts : undefined,
@@ -795536,7 +795581,7 @@ function WelcomeV2() {
795536
795581
  dimColor: true,
795537
795582
  children: [
795538
795583
  "v",
795539
- "1.80.6"
795584
+ "1.80.8"
795540
795585
  ]
795541
795586
  }, undefined, true, undefined, this)
795542
795587
  ]
@@ -796796,7 +796841,7 @@ function completeOnboarding() {
796796
796841
  saveGlobalConfig((current) => ({
796797
796842
  ...current,
796798
796843
  hasCompletedOnboarding: true,
796799
- lastOnboardingVersion: "1.80.6"
796844
+ lastOnboardingVersion: "1.80.8"
796800
796845
  }));
796801
796846
  }
796802
796847
  function showDialog(root2, renderer) {
@@ -801942,7 +801987,7 @@ function appendToLog(path28, message) {
801942
801987
  cwd: getFsImplementation().cwd(),
801943
801988
  userType: process.env.USER_TYPE,
801944
801989
  sessionId: getSessionId(),
801945
- version: "1.80.6"
801990
+ version: "1.80.8"
801946
801991
  };
801947
801992
  getLogWriter(path28).write(messageWithTimestamp);
801948
801993
  }
@@ -806106,8 +806151,8 @@ async function getEnvLessBridgeConfig() {
806106
806151
  }
806107
806152
  async function checkEnvLessBridgeMinVersion() {
806108
806153
  const cfg = await getEnvLessBridgeConfig();
806109
- if (cfg.min_version && lt("1.80.6", cfg.min_version)) {
806110
- return `Your version of UR (${"1.80.6"}) is too old for Remote Control.
806154
+ if (cfg.min_version && lt("1.80.8", cfg.min_version)) {
806155
+ return `Your version of UR (${"1.80.8"}) is too old for Remote Control.
806111
806156
  Version ${cfg.min_version} or higher is required. Run \`ur update\` to update.`;
806112
806157
  }
806113
806158
  return null;
@@ -806581,7 +806626,7 @@ async function initBridgeCore(params) {
806581
806626
  const rawApi = createBridgeApiClient({
806582
806627
  baseUrl,
806583
806628
  getAccessToken,
806584
- runnerVersion: "1.80.6",
806629
+ runnerVersion: "1.80.8",
806585
806630
  onDebug: logForDebugging,
806586
806631
  onAuth401,
806587
806632
  getTrustedDeviceToken
@@ -816054,7 +816099,7 @@ function getAgUiCapabilities() {
816054
816099
  name: "UR-Nexus",
816055
816100
  type: "ur-nexus",
816056
816101
  description: "Provider-flexible, local-first autonomous engineering workflow agent.",
816057
- version: "1.80.6",
816102
+ version: "1.80.8",
816058
816103
  provider: "UR",
816059
816104
  documentationUrl: "https://github.com/Maitham16/UR/blob/master/docs/AG_UI.md"
816060
816105
  },
@@ -817281,7 +817326,7 @@ function createMCPServer(cwd4, debug2, verbose) {
817281
817326
  };
817282
817327
  const server2 = new Server({
817283
817328
  name: "ur-nexus",
817284
- version: "1.80.6"
817329
+ version: "1.80.8"
817285
817330
  }, {
817286
817331
  capabilities: {
817287
817332
  tools: {}
@@ -818485,7 +818530,7 @@ function thrownResponse(error40) {
818485
818530
  }
818486
818531
  async function createUrMcp2026Runtime(options5) {
818487
818532
  const server2 = createMCPServer(options5.cwd, options5.debug === true, options5.verbose === true);
818488
- const client2 = new Client({ name: "ur-mcp-2026-adapter", version: "1.80.6" }, { capabilities: {} });
818533
+ const client2 = new Client({ name: "ur-mcp-2026-adapter", version: "1.80.8" }, { capabilities: {} });
818489
818534
  const [clientTransport, serverTransport] = createLinkedTransportPair();
818490
818535
  try {
818491
818536
  await server2.connect(serverTransport);
@@ -818496,7 +818541,7 @@ async function createUrMcp2026Runtime(options5) {
818496
818541
  }
818497
818542
  const runtime2 = new Mcp2026Runtime({
818498
818543
  cwd: options5.cwd,
818499
- version: "1.80.6",
818544
+ version: "1.80.8",
818500
818545
  backend: {
818501
818546
  listTools: async () => {
818502
818547
  const listed = await client2.listTools();
@@ -821231,7 +821276,7 @@ async function update() {
821231
821276
  logEvent("tengu_update_check", {});
821232
821277
  const diagnostic2 = await getDoctorDiagnostic();
821233
821278
  const result = await checkUpgradeStatus({
821234
- currentVersion: "1.80.6",
821279
+ currentVersion: "1.80.8",
821235
821280
  packageName: UR_AGENT_PACKAGE_NAME,
821236
821281
  installationType: diagnostic2.installationType,
821237
821282
  latestVersion: () => getLatestNpmPackageVersion(UR_AGENT_PACKAGE_NAME)
@@ -822559,7 +822604,7 @@ ${customInstructions}` : customInstructions;
822559
822604
  }
822560
822605
  }
822561
822606
  logForDiagnosticsNoPII("info", "started", {
822562
- version: "1.80.6",
822607
+ version: "1.80.8",
822563
822608
  is_native_binary: isInBundledMode()
822564
822609
  });
822565
822610
  registerCleanup(async () => {
@@ -823346,7 +823391,7 @@ Usage: ur --remote "your task description"`, () => gracefulShutdown(1));
823346
823391
  pendingHookMessages
823347
823392
  }, renderAndRun);
823348
823393
  }
823349
- }).version("1.80.6 (UR-Nexus)", "-v, --version", "Output the version number");
823394
+ }).version("1.80.8 (UR-Nexus)", "-v, --version", "Output the version number");
823350
823395
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
823351
823396
  program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
823352
823397
  if (canUserConfigureAdvisor()) {
@@ -824473,7 +824518,7 @@ if (false) {}
824473
824518
  async function main2() {
824474
824519
  const args = process.argv.slice(2);
824475
824520
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
824476
- console.log(`${"1.80.6"} (UR-Nexus)`);
824521
+ console.log(`${"1.80.8"} (UR-Nexus)`);
824477
824522
  return;
824478
824523
  }
824479
824524
  if (args[0] === "a2a" && args[1] === "serve" && !args.includes("--help") && !args.includes("-h")) {
@@ -9,6 +9,19 @@ 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.80.8 Addition
13
+
14
+ | Addition | Surface | What it adds |
15
+ | --- | --- | --- |
16
+ | Provider-independent research routing | Shared Agent prompt and execution gate | Directs every model family to use the shipped `Explore` worker for task-free read-only research. If a model still labels an explicitly read-only research brief `general-purpose`, UR reduces it to protected Explore capabilities before task gating; write-capable and custom delegation remains gated. |
17
+
18
+ ## v1.80.7 Additions
19
+
20
+ | Addition | Surface | What it adds |
21
+ | --- | --- | --- |
22
+ | Recoverable local-model tool mismatch | Ollama native/text calls, streaming/non-streaming execution | Converts a valid call to a tool absent from the active profile into a safe `UnavailableTool` result instead of aborting the provider turn. Identical retries are bounded and omitted tools cannot be revived through legacy aliases. |
23
+ | Task-free read-only research | `Agent`, strict-hybrid task gate | Lets the main session launch the exact shipped `Explore` and `Plan` definitions before tasks exist in every parent permission mode, while forcing those children into plan permissions and keeping all custom or write-capable delegation gated. |
24
+
12
25
  ## v1.80.6 Addition
13
26
 
14
27
  | Addition | Surface | What it adds |
@@ -56,7 +56,14 @@ never blocked.
56
56
  do not carry a classified user turn; it is not a limit on investigation. Set
57
57
  it to `0` to require a task before every mutation. Set `enabled` to `false` to
58
58
  return to advisory task tracking. Profiles that omit `TaskCreate` are not
59
- gated, because they could not satisfy the requirement.
59
+ gated, because they could not satisfy the requirement. The main session may
60
+ launch UR's shipped `Explore` and `Plan` agents before a task exists in any
61
+ permission mode. These exact built-in definitions are forced read-only; custom,
62
+ write-capable, nested, named/team, and worktree delegation still requires an
63
+ actionable parent task. As provider-independent compatibility, an unnamed
64
+ main-session `general-purpose` call whose own prompt explicitly declares both
65
+ research intent and no file writes is reduced to the shipped Explore definition
66
+ before the gate. It never receives general-purpose tools through this path.
60
67
 
61
68
  ## Model Providers
62
69
 
@@ -83,14 +83,17 @@ ur provider status
83
83
  different source. Timeouts, `408`, `409`, `425`, `429`, and `5xx` responses
84
84
  remain retryable because they may be transient.
85
85
 
86
- ### Plan mode says `TaskListRequired`
86
+ ### A built-in research agent says `TaskListRequired`
87
87
 
88
88
  - Likely cause on UR 1.80.3–1.80.5: the strict task gate treated either the
89
89
  active plan file or early read-only research delegation as an untracked
90
90
  project mutation, creating a circular requirement before planning finished.
91
- - Fix: upgrade to UR 1.80.6 or newer. The exact active plan file and main-thread
92
- delegation to UR's shipped read-only `Explore` and `Plan` agents are allowed
93
- before tasks exist. Approved plans are synchronized into visible
91
+ - UR 1.80.6 fixed this inside Plan Mode. UR 1.80.7 extends the same safe rule to
92
+ ordinary main-session research: upgrade to 1.80.7 or newer. The exact active
93
+ plan file and main-thread delegation to UR's shipped read-only `Explore` and
94
+ `Plan` agents are allowed before tasks exist. The child is forced into plan
95
+ permissions even if the parent uses Accept Edits or Approve All. Approved
96
+ plans are synchronized into visible
94
97
  implementation and verification tasks before the first project mutation.
95
98
  Other files and write-capable delegation remain protected. Existing
96
99
  actionable tasks are preserved.
@@ -99,6 +102,26 @@ ur provider status
99
102
  agents without a parent task: create the requested tasks or finish and
100
103
  approve the plan first. Disabling `tasks.requireBeforeChanges` is no longer
101
104
  needed for normal plan mode.
105
+ - If an API, local, or subscription-CLI model still returns this error for an
106
+ explicitly read-only research brief on 1.80.7, upgrade to 1.80.8. Some models
107
+ emitted `subagent_type: "general-purpose"` despite the read-only instruction.
108
+ UR 1.80.8 routes that narrow contract to the protected Explore worker before
109
+ the gate. A real general-purpose or implementation worker is still expected
110
+ to require a task.
111
+
112
+ ### Ollama stops with `unavailable tool "WebSearch"`
113
+
114
+ - Cause on UR 1.80.6 and older: a local model requested a provider-hosted tool
115
+ that was not present in its active tool profile. The Ollama adapter treated
116
+ the valid but unavailable tool name as a fatal provider-response error, so
117
+ the parent could not receive the research agents' remaining useful results.
118
+ - Fix: upgrade to UR 1.80.7 or newer. UR now returns a recoverable
119
+ `UnavailableTool` result without executing the call. The agent is instructed
120
+ to use an available alternative or return its partial result, and repeated
121
+ identical unavailable calls are bounded. This applies to native and
122
+ text-form calls in streaming and non-streaming Ollama responses.
123
+ - `WebSearch` is still not fabricated for a model or profile that does not have
124
+ it. Malformed tool names and malformed arguments still fail closed.
102
125
 
103
126
  ## Providers and models
104
127
 
package/docs/USAGE.md CHANGED
@@ -470,11 +470,15 @@ older builds are hidden and removed at the next prompt boundary.
470
470
 
471
471
  Plan mode has one narrow exception to the mutation gate: UR may write or edit
472
472
  the exact plan file for the active session while the rest of the workspace
473
- remains read-only. The main session may also delegate early research to UR's
474
- shipped `Explore` and `Plan` agents before tasks exist. Those two definitions
475
- are mechanically held in plan permission mode; custom overrides,
476
- general-purpose agents, nested agents, team workers, and worktree agents still
477
- require an actionable parent task. When the user approves the plan,
473
+ remains read-only. In any permission mode, the main session may delegate early
474
+ research to UR's shipped `Explore` and `Plan` agents before tasks exist. Those
475
+ two definitions are mechanically forced into plan permission mode even when
476
+ the parent is in Accept Edits or Approve All. Models are instructed to select
477
+ `subagent_type="Explore"` for this work. If a provider still labels an explicit
478
+ read-only research brief `general-purpose`, UR reduces that main-session call
479
+ to the shipped Explore definition before gating. Ordinary general-purpose
480
+ work, custom overrides, nested agents, named/team workers, worktrees, and cwd
481
+ overrides still require an actionable parent task. When the user approves the plan,
478
482
  `ExitPlanMode` preserves any existing actionable board or creates a bounded set
479
483
  of professional, deduplicated implementation tasks plus a verification task
480
484
  that depends on them. Implementation therefore starts with visible tracking
@@ -19,22 +19,43 @@ You need:
19
19
 
20
20
  ```sh
21
21
  ur --version
22
- # expected for this release: "1.80.6 (UR-Nexus)"
22
+ # expected for this release: "1.80.8 (UR-Nexus)"
23
23
  ```
24
24
 
25
- ### 0.0 Plan research delegation starts cleanly (1.80.6)
25
+ ### 0.0 Read-only research delegation starts cleanly (1.80.8)
26
26
 
27
- Start an interactive session with task enforcement enabled and ask UR to plan a
28
- change that requires codebase research. Before any task exists, built-in
29
- `Explore` and `Plan` agent calls should initialize without `TaskListRequired`.
30
- Custom or general-purpose agents should remain blocked until they have an
31
- actionable parent task. The deterministic regressions are:
27
+ Start an interactive session with task enforcement enabled and ask UR to
28
+ research a change, both normally and from Plan Mode. Before any task exists,
29
+ built-in `Explore` and `Plan` agent calls should initialize without
30
+ `TaskListRequired`. Their workers remain read-only even when the parent uses
31
+ Accept Edits or Approve All. Custom agents and ordinary general-purpose agents
32
+ should remain blocked until they have an actionable parent task.
33
+
34
+ Repeat with multiple available model families. A model may correctly emit
35
+ `subagent_type: "Explore"`; if it instead emits `general-purpose` with an
36
+ explicit read-only research/no-file-write brief, UR must safely reduce it to
37
+ Explore and start without a failed `TaskListRequired` attempt. A
38
+ general-purpose implementation brief must remain blocked. The deterministic
39
+ regressions are:
32
40
 
33
41
  ```sh
34
42
  bun test test/taskListGate.test.ts test/toolExecutionFinalInput.test.ts
35
43
  ```
36
44
 
37
- ### 0.0.1 Plan approval creates visible tasks (1.80.5)
45
+ ### 0.0.1 Unavailable Ollama tools recover (1.80.7)
46
+
47
+ With an Ollama model, ask for research that mentions WebSearch. If WebSearch is
48
+ not in the active profile, UR should reject that call safely and the agent
49
+ should continue with available tools or its useful partial result. It must not
50
+ end the parent turn with `Ollama response returned unavailable tool`. Native
51
+ and text-form, streaming and non-streaming regressions are covered by:
52
+
53
+ ```sh
54
+ bun test test/ollamaToolCalls.test.ts test/kimiToolCalls.test.ts \
55
+ test/repeatedFailureGuard.test.ts test/streamingToolExecutor.test.ts
56
+ ```
57
+
58
+ ### 0.0.2 Plan approval creates visible tasks (1.80.5)
38
59
 
39
60
  Start an interactive session with task enforcement enabled, ask for a
40
61
  multi-file change, and let the agent enter plan mode. Expected lifecycle:
@@ -45,7 +45,7 @@
45
45
  <main id="content" class="content">
46
46
  <header class="topbar">
47
47
  <div>
48
- <p class="eyebrow">Version 1.80.6</p>
48
+ <p class="eyebrow">Version 1.80.8</p>
49
49
  <h1>UR-Nexus Documentation</h1>
50
50
  <p class="lead">A practical, tutorial-style reference for installing, configuring, automating, extending, and operating UR-Nexus.</p>
51
51
  </div>
@@ -7,7 +7,7 @@ plugins {
7
7
  }
8
8
 
9
9
  group = "dev.urnexus"
10
- version = "1.80.6"
10
+ version = "1.80.8"
11
11
 
12
12
  repositories {
13
13
  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.80.6",
5
+ "version": "1.80.8",
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.80.6",
3
+ "version": "1.80.8",
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",