mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-11-11 07:07:22 +00:00
Added an introduction and an onboarding chat to the BeyondFacts Lab (#1178)
This commit is contained in:
1 parent
79e0c80031
commit
22d94eb8fd
35 files changed
+1377
-361
No files matched your search
@@ -35,7 +35,7 @@ public sealed class BeyondFactsLabStoreThreadTests
|
||||
var store = this.CreateStore();
|
||||
var created = await store.CreateAsync("Panel");
|
||||
|
||||
var thread = await store.LoadThreadAsync(new BflThreadLocation(created.ProjectId, BflStep.FRAMEWORK));
|
||||
var thread = await store.LoadThreadAsync(new BflStepThreadLocation(created.ProjectId, BflStep.FRAMEWORK));
|
||||
|
||||
Assert.That(thread, Is.Null);
|
||||
}
|
||||
@@ -45,10 +45,11 @@ public sealed class BeyondFactsLabStoreThreadTests
|
||||
{
|
||||
var store = this.CreateStore();
|
||||
var created = await store.CreateAsync("Panel");
|
||||
var location = new BflThreadLocation(created.ProjectId, BflStep.KNOWLEDGE);
|
||||
var location = new BflStepThreadLocation(created.ProjectId, BflStep.KNOWLEDGE);
|
||||
var thread = WithMessage(BflThreadFactory.Create(location), "Worauf beruht meine Expertise?");
|
||||
|
||||
var changed = await store.SaveThreadAsync(location, thread);
|
||||
await store.SaveThreadAsync(location, thread);
|
||||
var changed = await store.LoadAsync(created.ProjectId);
|
||||
var loaded = await this.CreateStore().LoadThreadAsync(location);
|
||||
|
||||
using (Assert.EnterMultipleScope())
|
||||
@@ -57,7 +58,7 @@ public sealed class BeyondFactsLabStoreThreadTests
|
||||
Assert.That(loaded!.ChatId, Is.EqualTo(location.ChatId));
|
||||
Assert.That(loaded.Blocks, Has.Count.EqualTo(1));
|
||||
Assert.That(((ContentText)loaded.Blocks[0].Content!).Text, Is.EqualTo("Worauf beruht meine Expertise?"));
|
||||
Assert.That(changed.ModifiedAtUtc, Is.GreaterThan(created.ModifiedAtUtc), "A conversation is work on the preparation.");
|
||||
Assert.That(changed!.ModifiedAtUtc, Is.GreaterThan(created.ModifiedAtUtc), "A conversation is work on the preparation.");
|
||||
Assert.That(File.Exists(Path.Combine(this.RootDirectory, created.ProjectId.ToString("D"), "steps", "02-knowledge", "thread.json")), Is.True);
|
||||
}
|
||||
}
|
||||
@@ -67,9 +68,9 @@ public sealed class BeyondFactsLabStoreThreadTests
|
||||
{
|
||||
var store = this.CreateStore();
|
||||
var created = await store.CreateAsync("Panel");
|
||||
var thread = BflThreadFactory.Create(new BflThreadLocation(created.ProjectId, BflStep.STRATEGY));
|
||||
var thread = BflThreadFactory.Create(new BflStepThreadLocation(created.ProjectId, BflStep.STRATEGY));
|
||||
|
||||
await Assert.ThrowsAsync<ArgumentException>(async () => await store.SaveThreadAsync(new BflThreadLocation(created.ProjectId, BflStep.FRAMEWORK), thread));
|
||||
await Assert.ThrowsAsync<ArgumentException>(async () => await store.SaveThreadAsync(new BflStepThreadLocation(created.ProjectId, BflStep.FRAMEWORK), thread));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -77,7 +78,7 @@ public sealed class BeyondFactsLabStoreThreadTests
|
||||
{
|
||||
var store = this.CreateStore();
|
||||
var created = await store.CreateAsync("Panel");
|
||||
var location = new BflThreadLocation(created.ProjectId, BflStep.FRAMEWORK);
|
||||
var location = new BflStepThreadLocation(created.ProjectId, BflStep.FRAMEWORK);
|
||||
await store.DeleteAsync(created.ProjectId);
|
||||
|
||||
await Assert.ThrowsAsync<FileNotFoundException>(async () => await store.SaveThreadAsync(location, BflThreadFactory.Create(location)));
|
||||
@@ -90,8 +91,8 @@ public sealed class BeyondFactsLabStoreThreadTests
|
||||
{
|
||||
var store = this.CreateStore();
|
||||
var created = await store.CreateAsync("Panel");
|
||||
var strategy = new BflThreadLocation(created.ProjectId, BflStep.STRATEGY);
|
||||
var framework = new BflThreadLocation(created.ProjectId, BflStep.FRAMEWORK);
|
||||
var strategy = new BflStepThreadLocation(created.ProjectId, BflStep.STRATEGY);
|
||||
var framework = new BflStepThreadLocation(created.ProjectId, BflStep.FRAMEWORK);
|
||||
await store.SaveThreadAsync(strategy, BflThreadFactory.Create(strategy));
|
||||
var stepsDirectory = Path.Combine(this.RootDirectory, created.ProjectId.ToString("D"), "steps");
|
||||
Directory.CreateDirectory(Path.Combine(stepsDirectory, "01-framework"));
|
||||
@@ -109,7 +110,7 @@ public sealed class BeyondFactsLabStoreThreadTests
|
||||
{
|
||||
var store = this.CreateStore();
|
||||
var created = await store.CreateAsync("Panel");
|
||||
var location = new BflThreadLocation(created.ProjectId, BflStep.FRAMEWORK);
|
||||
var location = new BflStepThreadLocation(created.ProjectId, BflStep.FRAMEWORK);
|
||||
var path = Path.Combine(this.RootDirectory, created.ProjectId.ToString("D"), "steps", "01-framework", "thread.json");
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path)!);
|
||||
await File.WriteAllTextAsync(path, "{ damaged");
|
||||
@@ -127,7 +128,7 @@ public sealed class BeyondFactsLabStoreThreadTests
|
||||
{
|
||||
var store = this.CreateStore();
|
||||
var created = await store.CreateAsync("Panel");
|
||||
var location = new BflThreadLocation(created.ProjectId, BflStep.FRAMEWORK);
|
||||
var location = new BflStepThreadLocation(created.ProjectId, BflStep.FRAMEWORK);
|
||||
await store.SaveThreadAsync(location, WithMessage(BflThreadFactory.Create(location), "Hallo"));
|
||||
|
||||
await store.DeleteThreadAsync(location);
|
||||
@@ -141,8 +142,8 @@ public sealed class BeyondFactsLabStoreThreadTests
|
||||
var store = this.CreateStore();
|
||||
var first = await store.CreateAsync("Panel");
|
||||
var second = await store.CreateAsync("Interview");
|
||||
var firstStrategy = new BflThreadLocation(first.ProjectId, BflStep.STRATEGY);
|
||||
var secondFramework = new BflThreadLocation(second.ProjectId, BflStep.FRAMEWORK);
|
||||
var firstStrategy = new BflStepThreadLocation(first.ProjectId, BflStep.STRATEGY);
|
||||
var secondFramework = new BflStepThreadLocation(second.ProjectId, BflStep.FRAMEWORK);
|
||||
await store.SaveThreadAsync(firstStrategy, BflThreadFactory.Create(firstStrategy));
|
||||
await store.SaveThreadAsync(secondFramework, BflThreadFactory.Create(secondFramework));
|
||||
|
||||
@@ -157,10 +158,58 @@ public sealed class BeyondFactsLabStoreThreadTests
|
||||
Assert.That(locations[firstStrategy.ChatId], Is.EqualTo(firstStrategy));
|
||||
Assert.That(locations[secondFramework.ChatId], Is.EqualTo(secondFramework));
|
||||
Assert.That(store.GetThreadWrittenAt(firstStrategy), Is.Not.Null);
|
||||
Assert.That(store.GetThreadWrittenAt(new BflThreadLocation(first.ProjectId, BflStep.FRAMEWORK)), Is.Null);
|
||||
Assert.That(store.GetThreadWrittenAt(new BflStepThreadLocation(first.ProjectId, BflStep.FRAMEWORK)), Is.Null);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TheOnboardingIsStoredApartFromThePreparations()
|
||||
{
|
||||
var store = this.CreateStore();
|
||||
var location = BflOnboardingThreadLocation.INSTANCE;
|
||||
|
||||
await store.SaveThreadAsync(location, WithMessage(BflThreadFactory.Create(location), "Passt das Lab zu meinem Interview?"));
|
||||
var otherStore = this.CreateStore();
|
||||
var loaded = await otherStore.LoadThreadAsync(location);
|
||||
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(loaded, Is.Not.Null);
|
||||
Assert.That(loaded!.ChatId, Is.EqualTo(BflThreadId.ONBOARDING));
|
||||
Assert.That(((ContentText)loaded.Blocks[0].Content!).Text, Is.EqualTo("Passt das Lab zu meinem Interview?"));
|
||||
Assert.That(File.Exists(Path.Combine(this.RootDirectory, "onboarding", "thread.json")), Is.True);
|
||||
Assert.That(await otherStore.ListProjectsAsync(), Is.Empty, "The folder of the onboarding is no preparation.");
|
||||
Assert.That(otherStore.ReadAllThreadLocations()[BflThreadId.ONBOARDING], Is.EqualTo(location));
|
||||
Assert.That(otherStore.GetThreadWrittenAt(location), Is.Not.Null);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task StartingTheOnboardingOverDeletesIt()
|
||||
{
|
||||
var store = this.CreateStore();
|
||||
var location = BflOnboardingThreadLocation.INSTANCE;
|
||||
await store.SaveThreadAsync(location, WithMessage(BflThreadFactory.Create(location), "Hallo"));
|
||||
|
||||
await store.DeleteThreadAsync(location);
|
||||
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(await store.LoadThreadAsync(location), Is.Null);
|
||||
Assert.That(store.ReadAllThreadLocations(), Does.Not.ContainKey(BflThreadId.ONBOARDING));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task AChatOfAStepIsNotStoredAsTheOnboarding()
|
||||
{
|
||||
var store = this.CreateStore();
|
||||
var created = await store.CreateAsync("Panel");
|
||||
var thread = BflThreadFactory.Create(new BflStepThreadLocation(created.ProjectId, BflStep.FRAMEWORK));
|
||||
|
||||
await Assert.ThrowsAsync<ArgumentException>(async () => await store.SaveThreadAsync(BflOnboardingThreadLocation.INSTANCE, thread));
|
||||
}
|
||||
|
||||
private static ChatThread WithMessage(ChatThread thread, string text)
|
||||
{
|
||||
thread.Blocks.Add(new ContentBlock
|
||||
|
||||
@@ -24,6 +24,19 @@ public sealed class BflModelRequirementsTests
|
||||
Assert.That(BflModelRequirements.HasEnoughContext(ContextWindow.Of(defaultTokens)), Is.EqualTo(expected));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TheOnboardingRunsWithASmallWindow()
|
||||
{
|
||||
var smallWindow = ContextWindow.Of(8_192);
|
||||
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(BflModelRequirements.HasEnoughContext(BflOnboardingThreadLocation.INSTANCE, smallWindow), Is.True, "The onboarding leaves out the guide.");
|
||||
Assert.That(BflModelRequirements.HasEnoughContext(new BflStepThreadLocation(Guid.NewGuid(), BflStep.FRAMEWORK), smallWindow), Is.False);
|
||||
Assert.That(BflModelRequirements.HasEnoughContext(new BflStepThreadLocation(Guid.NewGuid(), BflStep.FRAMEWORK), ContextWindow.Of(BflModelRequirements.MINIMUM_CONTEXT_TOKENS)), Is.True);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AWindowWhichOnlyAnOperatorCouldRaiseIsNotEnough()
|
||||
{
|
||||
|
||||
@@ -67,6 +67,55 @@ public sealed class BflPromptComposerTests
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TheOnboardingFillsEveryPlaceholderWithoutTheGuide()
|
||||
{
|
||||
var parts = await BflPromptLibrary.LoadOnboardingPartsAsync(AddressForm.FORMAL);
|
||||
var knowledge = await BflPromptLibrary.ReadAsync(BflPromptLibrary.KNOWLEDGE_PATH);
|
||||
|
||||
var prompt = BflPromptComposer.ComposeOnboarding(parts, "Deutsch");
|
||||
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(prompt, Does.Not.Contain("{{"));
|
||||
Assert.That(prompt, Does.Contain("Antworte auf Deutsch."));
|
||||
Assert.That(prompt, Does.Not.Contain(knowledge.Trim()[..200]), "The onboarding stays short, so it leaves out the guide.");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TheFormOfAddressDecidesTheInstructionOfTheOnboarding()
|
||||
{
|
||||
var formal = BflPromptComposer.ComposeOnboarding(await BflPromptLibrary.LoadOnboardingPartsAsync(AddressForm.FORMAL), "Deutsch");
|
||||
var informal = BflPromptComposer.ComposeOnboarding(await BflPromptLibrary.LoadOnboardingPartsAsync(AddressForm.INFORMAL), "Deutsch");
|
||||
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(formal, Does.Contain("mit „Sie“"));
|
||||
Assert.That(formal, Does.Not.Contain("mit „du“"));
|
||||
Assert.That(informal, Does.Contain("mit „du“"));
|
||||
Assert.That(informal, Does.Not.Contain("mit „Sie“"));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TheOnboardingIsTheSameOnEverySystem()
|
||||
{
|
||||
var parts = new BflOnboardingPromptParts("Sprache: {{RESPONSE_LANGUAGE}}\r\n{{ADDRESS_FORM}}\r\nEnde", " Anrede\r\n");
|
||||
|
||||
var prompt = BflPromptComposer.ComposeOnboarding(parts, "Deutsch");
|
||||
|
||||
Assert.That(prompt, Is.EqualTo("Sprache: Deutsch\nAnrede\nEnde"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TheOnboardingKnowsNoDetailsOfAPreparation()
|
||||
{
|
||||
var parts = new BflOnboardingPromptParts("{{DETAILS}}", "Anrede");
|
||||
|
||||
Assert.Throws<FormatException>(() => BflPromptComposer.ComposeOnboarding(parts, "Deutsch"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TheLanguageOfTheAnswersIsNamed()
|
||||
{
|
||||
|
||||
@@ -24,6 +24,16 @@ public sealed class BflPromptLibraryTests
|
||||
/// </remarks>
|
||||
private const int MAX_FIXED_PROMPT_CHARACTERS = 90_000;
|
||||
|
||||
/// <summary>
|
||||
/// How many characters the fixed part of the prompt of the onboarding may have: the prompt and the longest form of
|
||||
/// address.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// About 4,000 tokens. The onboarding asks for no minimum context window, unlike the steps, so it has to leave room
|
||||
/// for a conversation in small models as well.
|
||||
/// </remarks>
|
||||
private const int MAX_ONBOARDING_PROMPT_CHARACTERS = 16_000;
|
||||
|
||||
[Test]
|
||||
public async Task EveryPromptComesWithTheApp()
|
||||
{
|
||||
@@ -66,4 +76,30 @@ public sealed class BflPromptLibraryTests
|
||||
|
||||
Assert.That(core.Length + knowledge.Length + longestStep + longestAddress, Is.LessThanOrEqualTo(MAX_FIXED_PROMPT_CHARACTERS));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task EveryOpeningRequestNamesASectionOfItsPrompt()
|
||||
{
|
||||
var core = (await BflPromptLibrary.ReadAsync(BflPromptLibrary.CORE_PATH)).ReplaceLineEndings("\n");
|
||||
var onboarding = (await BflPromptLibrary.ReadAsync(BflPromptLibrary.ONBOARDING_PATH)).ReplaceLineEndings("\n");
|
||||
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(BflConversationService.OpeningRequestFor(new BflStepThreadLocation(Guid.NewGuid(), BflStep.FRAMEWORK)), Does.Contain("„Dieser Schritt“"));
|
||||
Assert.That(core, Does.Contain("\n# Dieser Schritt\n"));
|
||||
Assert.That(BflConversationService.OpeningRequestFor(BflOnboardingThreadLocation.INSTANCE), Does.Contain("„Gesprächsführung“"));
|
||||
Assert.That(onboarding, Does.Contain("\n# Gesprächsführung\n"));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ThePromptOfTheOnboardingStaysShort()
|
||||
{
|
||||
var onboarding = await BflPromptLibrary.ReadAsync(BflPromptLibrary.ONBOARDING_PATH);
|
||||
var longestAddress = 0;
|
||||
foreach (var addressForm in Enum.GetValues<AddressForm>())
|
||||
longestAddress = Math.Max(longestAddress, (await BflPromptLibrary.ReadAsync(BflPromptLibrary.AddressPath(addressForm))).Length);
|
||||
|
||||
Assert.That(onboarding.Length + longestAddress, Is.LessThanOrEqualTo(MAX_ONBOARDING_PROMPT_CHARACTERS));
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ public sealed class BflThreadTests
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(BflThreadId.Of(PROJECT_ID, BflStep.STRATEGY), Is.EqualTo(expected));
|
||||
Assert.That(new BflThreadLocation(PROJECT_ID, BflStep.STRATEGY).ChatId, Is.EqualTo(expected));
|
||||
Assert.That(new BflStepThreadLocation(PROJECT_ID, BflStep.STRATEGY).ChatId, Is.EqualTo(expected));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,46 @@ public sealed class BflThreadTests
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TheIdOfTheOnboardingFollowsFromItsName()
|
||||
{
|
||||
// Computed independently, from SHA-256 over "beyondfacts-lab/thread/onboarding". A stored chat keeps its ID, so
|
||||
// this value never changes:
|
||||
var expected = Guid.Parse("b98423a4-8502-8ddd-8e56-df78ccd610ba");
|
||||
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(BflThreadId.ONBOARDING, Is.EqualTo(expected));
|
||||
Assert.That(BflOnboardingThreadLocation.INSTANCE.ChatId, Is.EqualTo(expected));
|
||||
Assert.That(BflOnboardingThreadLocation.INSTANCE.Key, Is.EqualTo("onboarding"));
|
||||
Assert.That(BflOnboardingThreadLocation.INSTANCE.ChatName, Is.EqualTo("onboarding"));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TheOnboardingSharesItsIdWithNoStep()
|
||||
{
|
||||
var stepIds = BflStep.All.Select(step => BflThreadId.Of(PROJECT_ID, step));
|
||||
|
||||
Assert.That(stepIds, Has.None.EqualTo(BflThreadId.ONBOARDING));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThePlaceOfAStepServesAsAKey()
|
||||
{
|
||||
BflThreadLocation first = new BflStepThreadLocation(PROJECT_ID, BflStep.STRATEGY);
|
||||
BflThreadLocation second = new BflStepThreadLocation(PROJECT_ID, BflStep.STRATEGY);
|
||||
|
||||
using (Assert.EnterMultipleScope())
|
||||
{
|
||||
Assert.That(first, Is.EqualTo(second));
|
||||
Assert.That(first.GetHashCode(), Is.EqualTo(second.GetHashCode()));
|
||||
Assert.That(first, Is.Not.EqualTo(new BflStepThreadLocation(PROJECT_ID, BflStep.FRAMEWORK)));
|
||||
Assert.That(first.Key, Is.EqualTo($"{PROJECT_ID:D}/05-strategy"));
|
||||
Assert.That(first.ChatName, Is.EqualTo("05-strategy"));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TheIdIsAVersion8Uuid()
|
||||
{
|
||||
@@ -55,7 +95,7 @@ public sealed class BflThreadTests
|
||||
[Test]
|
||||
public void ANewChatHasNothingButItsPlace()
|
||||
{
|
||||
var location = new BflThreadLocation(PROJECT_ID, BflStep.KNOWLEDGE);
|
||||
var location = new BflStepThreadLocation(PROJECT_ID, BflStep.KNOWLEDGE);
|
||||
|
||||
var thread = BflThreadFactory.Create(location);
|
||||
|
||||
@@ -73,7 +113,7 @@ public sealed class BflThreadTests
|
||||
[Test]
|
||||
public void AChatIsReadiedAsAChatOfTheLabWithoutToolsOrDataSources()
|
||||
{
|
||||
var thread = BflThreadFactory.Create(new BflThreadLocation(PROJECT_ID, BflStep.KNOWLEDGE));
|
||||
var thread = BflThreadFactory.Create(new BflStepThreadLocation(PROJECT_ID, BflStep.KNOWLEDGE));
|
||||
thread.DataSourceOptions.DisableDataSources = false;
|
||||
thread.RuntimeSelectedToolIds = ["web_search"];
|
||||
var provider = new AIStudio.Settings.Provider(1, "provider-1", "Test", LLMProviders.SELF_HOSTED, new Model("model", null));
|
||||
|
||||
@@ -124,7 +124,7 @@ public sealed class ProvenanceCleanupServiceTests
|
||||
// switches it on:
|
||||
var labStore = this.CreateLabStore();
|
||||
var project = await labStore.CreateAsync("Panel");
|
||||
var location = new BflThreadLocation(project.ProjectId, BflStep.KNOWLEDGE);
|
||||
var location = new BflStepThreadLocation(project.ProjectId, BflStep.KNOWLEDGE);
|
||||
var referenced = await this.store.Client.StoreAsync(location.ChatId, ProvenanceKind.WEB_PAGE, "of a page the chat of the lab read", null, TOKEN);
|
||||
var unreferenced = await this.store.Client.StoreAsync(location.ChatId, ProvenanceKind.WEB_PAGE, "of an answer the person removed", null, TOKEN);
|
||||
var thread = BflThreadFactory.Create(location);
|
||||
@@ -142,12 +142,33 @@ public sealed class ProvenanceCleanupServiceTests
|
||||
Assert.That(entries.Keys, Is.EquivalentTo(new[] { referenced.Value }), "The chat of the lab is read like any other chat.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task WhatTheOnboardingOfTheLabReceivedSurvivesTheCleanup()
|
||||
{
|
||||
var labStore = this.CreateLabStore();
|
||||
var location = BflOnboardingThreadLocation.INSTANCE;
|
||||
var referenced = await this.store.Client.StoreAsync(location.ChatId, ProvenanceKind.WEB_PAGE, "of a page the onboarding read", null, TOKEN);
|
||||
var thread = BflThreadFactory.Create(location);
|
||||
thread.Blocks.Add(new ContentBlock
|
||||
{
|
||||
ContentType = ContentType.TEXT,
|
||||
Role = ChatRole.AI,
|
||||
Content = new ContentText { Text = "Laut der Seite …", SourcePassages = [new SourcePassage { SourceUrl = "https://example.org/", ProvenanceId = referenced }] }
|
||||
});
|
||||
await labStore.SaveThreadAsync(location, thread);
|
||||
|
||||
await this.RunAsync(RestoreStateWith(report: null));
|
||||
|
||||
var entries = await this.store.Client.GetEntriesAsync([referenced!.Value], TOKEN);
|
||||
Assert.That(entries.Keys, Is.EquivalentTo(new[] { referenced.Value }), "The onboarding belongs to no preparation, but it is a chat of the lab all the same.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task WhatAChatOfADeletedPreparationReceivedIsRemoved()
|
||||
{
|
||||
var labStore = this.CreateLabStore();
|
||||
var project = await labStore.CreateAsync("Panel");
|
||||
var location = new BflThreadLocation(project.ProjectId, BflStep.KNOWLEDGE);
|
||||
var location = new BflStepThreadLocation(project.ProjectId, BflStep.KNOWLEDGE);
|
||||
await labStore.SaveThreadAsync(location, BflThreadFactory.Create(location));
|
||||
var entry = await this.store.Client.StoreAsync(location.ChatId, ProvenanceKind.WEB_PAGE, "of a page the chat of the lab read", null, TOKEN);
|
||||
await labStore.DeleteAsync(project.ProjectId);
|
||||
|
||||
Reference in new issue
Block a user