Fixed the Confluence search missing relevant pages (#1021)
Build and Release / Determine run mode (push) Waiting to run
Build and Release / Read metadata (push) Blocked by required conditions
Build and Release / Sync Flatpak repo (push) Blocked by required conditions
Build and Release / Collect Flatpak artifacts (push) Blocked by required conditions
Build and Release / Verify (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg,app,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage,updater, appimage) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg,app,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage,updater, appimage) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions

This commit is contained in:
Dominic Neuburg authored and GitHub committed 2026-10-04 12:50:52 +02:00
1 parent c4400c0ff6
commit 90c90910b3
4 files changed
+18 -10

No files matched your search

@@ -261,7 +261,14 @@ public sealed class ConfluenceSearchTool(WebPageRetrievalService webPageRetrieva
internal static Uri BuildSearchUrl(Uri baseUrl, string query, string? spaceKey)
{
var cql = $"text ~ \"{EscapeCqlValue(query)}\"";
//
// siteSearch is the field Confluence's own search box sends to this page: it finds the
// pages holding any of the words and ranks them by relevance. The text field, the one
// Atlassian documents, requires every word on the page and so missed pages the search
// box finds. Atlassian's CQL field reference does not list siteSearch, but the search
// page itself depends on it, and the REST API documentation uses it in its examples.
//
var cql = $"siteSearch ~ \"{EscapeCqlValue(query)}\"";
if (!string.IsNullOrWhiteSpace(spaceKey))
cql += $" and space=\"{EscapeCqlValue(spaceKey)}\"";
@@ -8,4 +8,5 @@
- Improved the Read Web Page tool. When you have not allowed the AI to choose web addresses freely, the tool now refuses every address that does not appear in your chat or in what the tools returned, instead of only asking the AI not to read it.
- Fixed a warning about the confidence level that stayed in the dialog for adding a local data source, even after you chose an embedding provider that meets it. The dialog now checks again whenever you change either of them, so a warning also appears when you switch to a provider that falls short.
- Fixed two confidence levels sharing the same name in the German user interface. Moderate is called "Mäßig" again, and Medium stays "Mittel".
- Fixed renaming an external data source (ERI server) leaving its secret behind under the old name in the keychain of your operating system.
- Fixed renaming an external data source (ERI server) leaving its secret behind under the old name in the keychain of your operating system.
- Fixed the Search Confluence tool missing pages that the search of your Confluence wiki finds. The tool now searches the same way as the search box of your wiki.
@@ -51,14 +51,14 @@ public sealed class ConfluenceSearchToolTests
var parameters = HttpUtility.ParseQueryString(searchUrl.Query);
Assert.That(searchUrl.GetLeftPart(UriPartial.Path), Is.EqualTo("https://wiki.example.org/confluence/dosearchsite.action"), "The search page lies below the context path of the wiki, even when the configured address lacks the final slash.");
Assert.That(parameters["cql"], Is.EqualTo("text ~ \"release plan\""));
Assert.That(parameters["cql"], Is.EqualTo("siteSearch ~ \"release plan\""), "The search box of the wiki sends the same field, so the tool finds the pages the user would find there.");
Assert.That(parameters["queryString"], Is.EqualTo("release plan"), "Confluence shows these words in its search field, so the page reads like a search the user made.");
Assert.That(ConfluenceSearchTool.IsWithinWiki(WIKI, searchUrl), Is.True);
}
[TestCase(@"plan"" or space = ""HR", @"text ~ ""plan\"" or space = \""HR""")]
[TestCase(@"C:\temp\", @"text ~ ""C:\\temp\\""")]
[TestCase(@"plan\"" or space = \""HR", @"text ~ ""plan\\\"" or space = \\\""HR""")]
[TestCase(@"plan"" or space = ""HR", @"siteSearch ~ ""plan\"" or space = \""HR""")]
[TestCase(@"C:\temp\", @"siteSearch ~ ""C:\\temp\\""")]
[TestCase(@"plan\"" or space = \""HR", @"siteSearch ~ ""plan\\\"" or space = \\\""HR""")]
public void TheQueryCannotLeaveItsCqlString(string query, string expectedCql)
{
//
@@ -72,13 +72,13 @@ public sealed class ConfluenceSearchToolTests
[Test]
public void ASpaceKeyRestrictsTheSearchToThatSpace()
{
Assert.That(Cql(ConfluenceSearchTool.BuildSearchUrl(WIKI, "release plan", "DEV")), Is.EqualTo("text ~ \"release plan\" and space=\"DEV\""));
Assert.That(Cql(ConfluenceSearchTool.BuildSearchUrl(WIKI, "release plan", "DEV")), Is.EqualTo("siteSearch ~ \"release plan\" and space=\"DEV\""));
}
[Test]
public void ASpaceKeyCannotLeaveItsCqlStringEither()
{
Assert.That(Cql(ConfluenceSearchTool.BuildSearchUrl(WIKI, "release plan", @"DEV"" or space = ""HR")), Is.EqualTo(@"text ~ ""release plan"" and space=""DEV\"" or space = \""HR"""), "The space key comes from the model as well, so it gets the same escaping as the words.");
Assert.That(Cql(ConfluenceSearchTool.BuildSearchUrl(WIKI, "release plan", @"DEV"" or space = ""HR")), Is.EqualTo(@"siteSearch ~ ""release plan"" and space=""DEV\"" or space = \""HR"""), "The space key comes from the model as well, so it gets the same escaping as the words.");
}
[TestCase(null)]
@@ -86,7 +86,7 @@ public sealed class ConfluenceSearchToolTests
[TestCase(" ")]
public void WithoutASpaceKeyTheWholeWikiIsSearched(string? spaceKey)
{
Assert.That(Cql(ConfluenceSearchTool.BuildSearchUrl(WIKI, "release plan", spaceKey)), Is.EqualTo("text ~ \"release plan\""), "An empty space key would otherwise ask for a space which does not exist and find nothing.");
Assert.That(Cql(ConfluenceSearchTool.BuildSearchUrl(WIKI, "release plan", spaceKey)), Is.EqualTo("siteSearch ~ \"release plan\""), "An empty space key would otherwise ask for a space which does not exist and find nothing.");
}
[Test]