mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-10 16:47:22 +00:00
Added OneNote sections as a document type (#1161)
This commit is contained in:
1 parent
677b650a79
commit
ce846e540e
24 files changed
+1142
-23
No files matched your search
@@ -12037,6 +12037,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T906183311"] = "How to update"
|
||||
-- A test configuration is active. It acts like a configuration of your organization and may, for example, approve assistant plugins. AI Studio removes it the next time you start the app.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T923110805"] = "A test configuration is active. It acts like a configuration of your organization and may, for example, approve assistant plugins. AI Studio removes it the next time you start the app."
|
||||
|
||||
-- We use this library to read the sections of OneNote notebooks. This allows us to insert OneNote pages into prompts and take them into account in RAG processes. The exact MPL-covered source is available from the repository linked and is identified in the offline notices bundled with AI Studio.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T938136536"] = "We use this library to read the sections of OneNote notebooks. This allows us to insert OneNote pages into prompts and take them into account in RAG processes. The exact MPL-covered source is available from the repository linked and is identified in the offline notices bundled with AI Studio."
|
||||
|
||||
-- Install Pandoc
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T986578435"] = "Install Pandoc"
|
||||
|
||||
|
||||
@@ -378,6 +378,7 @@
|
||||
<ThirdPartyComponent Name="dirs" Developer="soc, Wang Xuerui & Open Source Community" LicenseName="MIT" LicenseUrl="https://codeberg.org/dirs/dirs-rs/src/branch/main/LICENSE-MIT" RepositoryUrl="https://codeberg.org/dirs/dirs-rs" UseCase="@T("dirs determines the platform-specific local application data directory. AI Studio uses it so the Flatpak startup log is written to the same application data directory that Tauri uses.")"/>
|
||||
<ThirdPartyComponent Name="rand" Developer="Rust developers & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/rust-random/rand/blob/master/LICENSE-MIT" RepositoryUrl="https://github.com/rust-random/rand" UseCase="@T("We must generate random numbers, e.g., for securing the interprocess communication between the user interface and the runtime. The rand library is great for this purpose.")"/>
|
||||
<ThirdPartyComponent Name="pptx-to-md" Developer="Nils Kruthoff & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/nilskruthoff/pptx-parser/blob/master/LICENCE-MIT" RepositoryUrl="https://github.com/nilskruthoff/pptx-parser" UseCase="@T("We use this library to be able to read PowerPoint files. This allows us to insert content from slides into prompts and take PowerPoint files into account in RAG processes. We thank Nils Kruthoff for his work on this Rust crate.")"/>
|
||||
<ThirdPartyComponent Name="onenote_parser" Developer="Markus Siemens, Henry Heino, Mariusz Woloszyn, Laurent Cozic, pedr & Open Source Community" LicenseName="MPL-2.0" LicenseUrl="https://github.com/msiemens/onenote.rs/blob/master/LICENSE" RepositoryUrl="https://github.com/msiemens/onenote.rs" UseCase="@T("We use this library to read the sections of OneNote notebooks. This allows us to insert OneNote pages into prompts and take them into account in RAG processes. The exact MPL-covered source is available from the repository linked and is identified in the offline notices bundled with AI Studio.")"/>
|
||||
<ThirdPartyComponent Name="base64" Developer="Marshall Pierce, Alice Maz & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/marshallpierce/rust-base64/blob/master/LICENSE-MIT" RepositoryUrl="https://github.com/marshallpierce/rust-base64" UseCase="@T("For some data transfers, we need to encode the data in base64. This Rust library is great for this purpose.")"/>
|
||||
<ThirdPartyComponent Name="Rust Crypto" Developer="Artyom Pavlov, Tony Arcieri, Brian Warner, Arthur Gautier, Vlad Filippov, Friedel Ziegelmayer, Nicolas Stalder & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/RustCrypto/traits/blob/master/cipher/LICENSE-MIT" RepositoryUrl="https://github.com/RustCrypto" UseCase="@T("When transferring sensitive data between Rust runtime and .NET app, we encrypt the data. We use some libraries from the Rust Crypto project for this purpose: cipher, aes, cbc, pbkdf2, hmac, and sha2. We are thankful for the great work of the Rust Crypto project.")"/>
|
||||
<ThirdPartyComponent Name="rcgen" Developer="RustTLS developers, est31 & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/rustls/rcgen/blob/main/LICENSE" RepositoryUrl="https://github.com/rustls/rcgen" UseCase="@T("For the secure communication between the user interface and the runtime, we need to create certificates. This Rust library is great for this purpose.")"/>
|
||||
|
||||
+3
@@ -12039,6 +12039,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T906183311"] = "Update-Anleitung"
|
||||
-- A test configuration is active. It acts like a configuration of your organization and may, for example, approve assistant plugins. AI Studio removes it the next time you start the app.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T923110805"] = "Eine Testkonfiguration ist aktiv. Sie funktioniert wie eine Konfiguration Ihrer Organisation und kann beispielsweise Assistenten-Plugins freigeben. AI Studio entfernt sie beim nächsten Start der App."
|
||||
|
||||
-- We use this library to read the sections of OneNote notebooks. This allows us to insert OneNote pages into prompts and take them into account in RAG processes. The exact MPL-covered source is available from the repository linked and is identified in the offline notices bundled with AI Studio.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T938136536"] = "Wir verwenden diese Bibliothek, um die Abschnitte von OneNote-Notizbüchern zu lesen. So ist es möglich, OneNote-Seiten in Prompts einzufügen und in RAG-Prozessen zu berücksichtigen. Der genaue, unter der MPL lizenzierte Quellcode ist im verlinkten Repository verfügbar und in den mit AI Studio gebündelten Offline-Hinweisen angegeben."
|
||||
|
||||
-- Install Pandoc
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T986578435"] = "Pandoc installieren"
|
||||
|
||||
|
||||
+3
@@ -12039,6 +12039,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T906183311"] = "How to update"
|
||||
-- A test configuration is active. It acts like a configuration of your organization and may, for example, approve assistant plugins. AI Studio removes it the next time you start the app.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T923110805"] = "A test configuration is active. It acts like a configuration of your organization and may, for example, approve assistant plugins. AI Studio removes it the next time you start the app."
|
||||
|
||||
-- We use this library to read the sections of OneNote notebooks. This allows us to insert OneNote pages into prompts and take them into account in RAG processes. The exact MPL-covered source is available from the repository linked and is identified in the offline notices bundled with AI Studio.
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T938136536"] = "We use this library to read the sections of OneNote notebooks. This allows us to insert OneNote pages into prompts and take them into account in RAG processes. The exact MPL-covered source is available from the repository linked and is identified in the offline notices bundled with AI Studio."
|
||||
|
||||
-- Install Pandoc
|
||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T986578435"] = "Install Pandoc"
|
||||
|
||||
|
||||
@@ -7,6 +7,13 @@ public sealed class ContentStreamDocumentDetails
|
||||
[JsonPropertyName("page_number")]
|
||||
public int? PageNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the page is one the file itself knows, such as a page of a OneNote section, rather
|
||||
/// than one the runtime estimated from the page breaks of a Word or OpenDocument file.
|
||||
/// </summary>
|
||||
[JsonPropertyName("page_is_exact")]
|
||||
public bool PageIsExact { get; set; }
|
||||
|
||||
[JsonPropertyName("image")]
|
||||
public ContentStreamPptxImageData? Image { get; set; }
|
||||
}
|
||||
@@ -26,12 +26,13 @@ public sealed class DocumentManager
|
||||
|
||||
//
|
||||
// A Word or OpenDocument file carries no fixed page layout, so the runtime derives these
|
||||
// boundaries from page breaks and heuristics. We note the estimate as a comment rather
|
||||
// than as a heading: a heading would sit on the same level as the document's own first
|
||||
// level headings, leaving the AI unable to tell the structure of the document apart from
|
||||
// our boundaries. The presentation reader marks its slides the same way.
|
||||
// boundaries from page breaks and heuristics and says so. The pages of a OneNote section,
|
||||
// on the other hand, are those of the file. We note the page as a comment rather than as
|
||||
// a heading: a heading would sit on the same level as the document's own first level
|
||||
// headings, leaving the AI unable to tell the structure of the document apart from our
|
||||
// boundaries. The presentation reader marks its slides the same way.
|
||||
//
|
||||
this.currentPageContent.AppendLine($"<!-- Estimated page {pageNumber} -->");
|
||||
this.currentPageContent.AppendLine(metadata.Document?.PageIsExact is true ? $"<!-- Page {pageNumber} -->" : $"<!-- Estimated page {pageNumber} -->");
|
||||
this.currentPageContent.AppendLine();
|
||||
this.currentPageContent.Append(content);
|
||||
|
||||
|
||||
@@ -95,9 +95,10 @@ internal static class FileExclusions
|
||||
private static readonly string[] ALWAYS_EXCLUDED_FILES = ["Thumbs.db", "ehthumbs.db", "ehthumbs_vista.db", "desktop.ini", ".DS_Store", "Icon\r", OFFICE_LOCK_FILE_PATTERN];
|
||||
|
||||
/// <summary>
|
||||
/// Folders nobody ever wanted as content: what operating systems and ZIP files on macOS leave behind.
|
||||
/// Folders nobody ever wanted as content: what operating systems and ZIP files on macOS leave behind,
|
||||
/// and the recycle bin of a OneNote notebook, which holds the pages the user deleted.
|
||||
/// </summary>
|
||||
private static readonly string[] ALWAYS_EXCLUDED_FOLDERS = ["__MACOSX", "$RECYCLE.BIN", "System Volume Information"];
|
||||
private static readonly string[] ALWAYS_EXCLUDED_FOLDERS = ["__MACOSX", "$RECYCLE.BIN", "System Volume Information", "OneNote_RecycleBin"];
|
||||
|
||||
private static readonly char[] SEPARATORS = [';', '\r', '\n'];
|
||||
|
||||
|
||||
@@ -84,7 +84,11 @@ public static class FileTypes
|
||||
// The legacy binary ".ppt" is missing on purpose: AI Studio has no reader for it, so offering
|
||||
// it would only let users attach a file which cannot be read.
|
||||
public static readonly FileTypeFilter POWER_POINT = FileTypeFilter.Leaf("PowerPoint", "pptx", "odp");
|
||||
public static readonly FileTypeFilter MAIL = FileTypeFilter.Leaf(TB("Mail"), "eml", "msg", "mbox");
|
||||
|
||||
// Only the sections of a notebook carry its pages. The table of contents (".onetoc2") holds none,
|
||||
// and a package (".onepkg") would have to be unpacked into memory as a whole.
|
||||
public static readonly FileTypeFilter ONENOTE = FileTypeFilter.Leaf("OneNote", "one");
|
||||
public static readonly FileTypeFilter MAIL = FileTypeFilter.Leaf(TB("Mail"), "eml", "msg", "mbox");
|
||||
public static readonly FileTypeFilter LATEX = FileTypeFilter.Leaf("LaTeX", "tex", "bib", "sty", "cls", "log");
|
||||
|
||||
// Only the LaTeX document itself, without the auxiliary files of the LaTeX family: this is
|
||||
@@ -96,7 +100,7 @@ public static class FileTypes
|
||||
public static readonly FileTypeFilter POWER_POINT_PRESENTATION = FileTypeFilter.Leaf("PowerPoint", "pptx");
|
||||
|
||||
public static readonly FileTypeFilter OFFICE_FILES = FileTypeFilter.Parent(TB("Office Files"),
|
||||
WORD, SPREADSHEET, POWER_POINT, PDF);
|
||||
WORD, SPREADSHEET, POWER_POINT, ONENOTE, PDF);
|
||||
public static readonly FileTypeFilter DOCUMENT = FileTypeFilter.Parent(TB("Document"),
|
||||
TEXT, TABULAR, OFFICE_FILES, SOURCE_CODE, LATEX);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
- Added a setting for the size of the interface, which you find in the app settings. You can choose a size for each of your screens, and AI Studio switches to it when you move its window to another screen. Thanks, Paul Koudelka (`PaulKoudelka`), for this contribution.
|
||||
- Added formulas in code blocks to the chat: when an AI model puts a single formula into a code block marked as LaTeX, the chat now shows the formula instead of its code. A code block with a LaTeX document or with text in it stays code.
|
||||
- Added buttons to copy and save the formulas in the chat. When you point at a formula, you can copy its LaTeX code or save it as a LaTeX file, and the export menu of an answer offers its formulas as well.
|
||||
- Added support for OneNote sections (`.one`): you can attach them to chats and assistants and use them in your local data sources. AI Studio reads every page, including the text OneNote recognized in pictures and handwriting.
|
||||
- Improved the documentation for IT departments, which now lives in our [wiki](https://github.com/MindWorkAI/AI-Studio/wiki/Enterprise-IT). It is sorted by task, explains the setup on Windows, Linux, and macOS, and offers complete configurations for typical needs, such as using only local models. The link in the app settings leads there, and the wiki also holds the installation guide in English and German.
|
||||
- Improved the German translation throughout: we proofread all texts and corrected wrong labels as well as spelling and grammar mistakes. The texts now always address you formally and use the same terms everywhere.
|
||||
- Improved the security of the connection between the app window and AI Studio.
|
||||
|
||||
@@ -84,6 +84,36 @@ public sealed class ContentStreamPageNumberTests
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// The runtime estimates the pages of a Word or OpenDocument file from its page breaks, while a
|
||||
/// OneNote section knows its pages. The AI is told which of the two it reads.
|
||||
/// </remarks>
|
||||
[Test]
|
||||
public void OnlyAnEstimatedDocumentPageIsMarkedAsEstimated()
|
||||
{
|
||||
var estimatedStreamId = NewStreamId();
|
||||
var exactStreamId = NewStreamId();
|
||||
try
|
||||
{
|
||||
ContentStreamSseHandler.ProcessEvent(DocumentEvent(estimatedStreamId, 1, "A page of a Word file."));
|
||||
ContentStreamSseHandler.ProcessEvent(DocumentEvent(exactStreamId, 1, "A page of a OneNote section.", pageIsExact: true));
|
||||
|
||||
var estimated = ContentStreamSseHandler.Clear(estimatedStreamId);
|
||||
var exact = ContentStreamSseHandler.Clear(exactStreamId);
|
||||
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(estimated?.Content, Does.StartWith("<!-- Estimated page 1 -->"));
|
||||
Assert.That(exact?.Content, Does.StartWith("<!-- Page 1 -->"));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
ContentStreamSseHandler.Clear(estimatedStreamId);
|
||||
ContentStreamSseHandler.Clear(exactStreamId);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TheLastDocumentPageIsReleasedWithItsNumber()
|
||||
{
|
||||
@@ -176,11 +206,11 @@ public sealed class ContentStreamPageNumberTests
|
||||
Metadata = new ContentStreamPdfMetadata { Pdf = new() { PageNumber = pageNumber } },
|
||||
};
|
||||
|
||||
private static ContentStreamSseEvent DocumentEvent(string streamId, int pageNumber, string content) => new()
|
||||
private static ContentStreamSseEvent DocumentEvent(string streamId, int pageNumber, string content, bool pageIsExact = false) => new()
|
||||
{
|
||||
Content = content,
|
||||
StreamId = streamId,
|
||||
Metadata = new ContentStreamDocumentMetadata { Document = new() { PageNumber = pageNumber } },
|
||||
Metadata = new ContentStreamDocumentMetadata { Document = new() { PageNumber = pageNumber, PageIsExact = pageIsExact } },
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
@@ -145,6 +145,7 @@ public sealed class FileExclusionsTests
|
||||
[TestCase("Windows 11.pvm")]
|
||||
[TestCase("__MACOSX")]
|
||||
[TestCase("$RECYCLE.BIN")]
|
||||
[TestCase("OneNote_RecycleBin")]
|
||||
public void TheDefaultListExcludesTheseFolders(string folderName)
|
||||
{
|
||||
var folderPath = Path.Combine(Path.GetTempPath(), "test-data", folderName);
|
||||
|
||||
@@ -188,6 +188,19 @@ public class FileTypesTests
|
||||
path => Assert.That(validation.ValidateFilePath(path), Is.Not.Null));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A section of a OneNote notebook is a document, but the table of contents and the package of a
|
||||
/// notebook are not: the first holds no pages, and the runtime does not unpack the second. Both
|
||||
/// are binary, which the content check sees by their NUL bytes.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void OnlyTheSectionsOfAOneNoteNotebookAreDocuments()
|
||||
{
|
||||
AssertPath([0xE4, 0x52, 0x5C, 0x7B, 0x8C, 0xD8, 0xA7, 0x4D, 0x00, 0x00, 0x00, 0x00], "Meeting notes.one", true, FileTypes.DOCUMENT);
|
||||
AssertPath([0xA1, 0x2F, 0xFF, 0x43, 0xD9, 0xEF, 0x76, 0x4C, 0x00, 0x00, 0x00, 0x00], "Open Notebook.onetoc2", false, FileTypes.DOCUMENT);
|
||||
AssertPath([0x4D, 0x53, 0x43, 0x46, 0x00, 0x00, 0x00, 0x00], "Notebook.onepkg", false, FileTypes.DOCUMENT);
|
||||
}
|
||||
|
||||
[TestCase("recording.mp3")]
|
||||
[TestCase("meeting.mp4")]
|
||||
[TestCase("voice-recording.webm")]
|
||||
|
||||
@@ -20,6 +20,7 @@ public sealed class LocalRetrievalContentTypeTests
|
||||
[TestCase("pdf", ExpectedResult = RetrievalContentType.TEXT_DOCUMENT)]
|
||||
[TestCase("xlsx", ExpectedResult = RetrievalContentType.TEXT_SPREADSHEET)]
|
||||
[TestCase("pptx", ExpectedResult = RetrievalContentType.TEXT_PRESENTATION)]
|
||||
[TestCase("one", ExpectedResult = RetrievalContentType.TEXT_DOCUMENT)]
|
||||
[TestCase("unknown", ExpectedResult = RetrievalContentType.TEXT_DOCUMENT)]
|
||||
public RetrievalContentType AFileTypeTellsWhatItsPassagesAre(string fileType) => DataSourceLocalRetrievalService.GetRetrievalContentType(fileType);
|
||||
}
|
||||
Reference in new issue
Block a user