Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
a89b81a
iterating on insurance domain and puting generic import in collection…
rbuergi Oct 26, 2025
12437fa
enabling json in AwaitResponse and converting CollectionPlugin.Import…
rbuergi Oct 27, 2025
9f81dcf
correcting import with Configuration in ImportRequest
rbuergi Oct 27, 2025
164ba43
improving mapping for RiskImportAgent
rbuergi Oct 27, 2025
6326cc2
introducing geo coding.
rbuergi Oct 27, 2025
067a70e
iterating on slip
rbuergi Oct 28, 2025
fb270ca
iterating on indusrance domain
rbuergi Oct 28, 2025
182f444
iterating on insurance domain
rbuergi Oct 28, 2025
6e3a343
iterating on CollectionPlugin
rbuergi Oct 29, 2025
cd648ff
deferring messages until data context is initialized
rbuergi Oct 29, 2025
d7156d2
fixing nullability issues.
rbuergi Oct 29, 2025
364f54b
consolidating CollectionPlugin and ContentCollectionPlugin into Conte…
rbuergi Oct 30, 2025
91c6708
Treating callbacks as delivery finished
rbuergi Oct 30, 2025
481fd01
resolving deadlocks of content collection creation
rbuergi Oct 30, 2025
379736e
excluding large properties from logging.
rbuergi Oct 30, 2025
56aaa04
improving ContentPlugin
rbuergi Oct 30, 2025
97f5a21
renaming config
rbuergi Oct 30, 2025
14ff811
improving exception handling around messagehub start
rbuergi Oct 30, 2025
4f419fc
making deferrables more robust
rbuergi Oct 30, 2025
f358ff6
rename GetFile => GetContent
rbuergi Oct 30, 2025
f4e7d10
Refactoring deferrals.
rbuergi Oct 30, 2025
4d7f331
updating deferral conditions
rbuergi Oct 30, 2025
ca30dcb
fixing hub initialization
rbuergi Oct 30, 2025
52d8d03
improving Initialization for importhub
rbuergi Oct 31, 2025
80f4ea6
correcting startup mechanissm
rbuergi Oct 31, 2025
b4a0b81
fixing import unit test setup
rbuergi Oct 31, 2025
c46aa1f
undo appsettings
rbuergi Oct 31, 2025
c19bf2e
trying to make linking more robust
rbuergi Oct 31, 2025
bcb25e2
Moving all gate logic to MessageService
rbuergi Oct 31, 2025
0433e58
simplifying setup around DeferralContainer
rbuergi Oct 31, 2025
20da205
Update modules/Insurance/MeshWeaver.Insurance.Domain/LayoutAreas/Risk…
rbuergi Nov 1, 2025
b5d9ef8
fixing build error
rbuergi Nov 1, 2025
a1cdac5
increasing timeouts
rbuergi Nov 1, 2025
229a1ed
Improving threadsafety of MessageService
rbuergi Nov 1, 2025
089049d
introducing a test for pricing catalog.
rbuergi Nov 1, 2025
aafc7b8
Correcting deferrals in MessageService
rbuergi Nov 1, 2025
2b09569
corercting locking in MessageService
rbuergi Nov 1, 2025
696f684
avoid completing the deferral buffer.
rbuergi Nov 1, 2025
c72cb39
improving thread safety of MessageService
rbuergi Nov 1, 2025
b8c81f5
trying not to duplicate routing path.
rbuergi Nov 1, 2025
cf91a5a
fixing message construction for callbacks
rbuergi Nov 1, 2025
bf532b8
better treatment of deferred messages.
rbuergi Nov 1, 2025
4b015d7
placing locks outside removal of gate
rbuergi Nov 2, 2025
3701c37
Revert "improving thread safety of MessageService"
rbuergi Nov 2, 2025
32161cf
avoid duplicate messages
rbuergi Nov 2, 2025
c35171e
linking deferredBuffer to buffer rather than action block
rbuergi Nov 2, 2025
30df1a7
removing UpdateStreamRequest from list of non-deferred messages
rbuergi Nov 2, 2025
cd393da
eliminating delayedStart logic from layout areas
rbuergi Nov 2, 2025
1611dc8
getting rid of blocking await in LayoutAreaHost
rbuergi Nov 3, 2025
18033cc
improve logging
rbuergi Nov 3, 2025
eacd1d8
changing log level
rbuergi Nov 3, 2025
0df795a
missing .Synchronize in WorkspaceStreams
rbuergi Nov 3, 2025
322fbce
more fixes
rbuergi Nov 3, 2025
6d68462
fixing compilation
rbuergi Nov 3, 2025
35f8adb
more .Synchronize()
rbuergi Nov 3, 2025
2f67ded
setting logging to Warning
rbuergi Nov 3, 2025
48e724a
improving race conditions for closing activitieis
rbuergi Nov 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .claude/settings.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
"Bash(python:*)",
"Bash(python3:*)",
"Bash(test:*)",
"Bash(Select-Object -Last 20)"
"Bash(Select-Object -Last 20)",
"Bash(git mv:*)"
],
"deny": []
}
Expand Down
2 changes: 2 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
<PackageVersion Include="DocumentFormat.OpenXml" Version="3.3.0" />
<PackageVersion Include="EPS.Extensions.YamlMarkdown" Version="8.0.0" />
<PackageVersion Include="HtmlAgilityPack" Version="1.12.3" />
<PackageVersion Include="itext7" Version="9.3.0" />
<PackageVersion Include="JetBrains.Annotations" Version="2023.3.0" />
<PackageVersion Include="JsonPatch.Net" Version="3.3.0" />
<PackageVersion Include="JsonPath.Net" Version="2.1.1" />
Expand Down Expand Up @@ -142,6 +143,7 @@
<PackageVersion Include="Aspire.Azure.Data.Tables" Version="9.5.0" />
<PackageVersion Include="Microsoft.AspNetCore.Components.Web" Version="9.0.9" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageVersion Include="UglyToad.PdfPig" Version="1.7.0-custom-5" />
<PackageVersion Include="xunit.v3" Version="3.1.0" />
<PackageVersion Include="xunit.v3.assert" Version="3.1.0" />
<PackageVersion Include="xunit.v3.extensibility.core" Version="3.1.0" />
Expand Down
Binary file modified modules/Insurance/Files/Microsoft/2026/Microsoft.xlsx
Binary file not shown.
71 changes: 40 additions & 31 deletions modules/Insurance/Files/Microsoft/2026/Slip.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,69 +14,78 @@
**Address:** One Microsoft Way, Redmond, WA 98052, United States

## Period of Insurance
**From:** 1 January 2026
**To:** 31 December 2026
**From:** 1 January 2026
**To:** 31 December 2026
**Local Standard Time at the address of the Insured**

---

## Reinsurance Terms

**Estimated Premium Income (EPI):** USD 200,000,000
**Brokerage:** 10%

---

## Coverage Sections

### 1. Fire Damage

- **Layer 1:**
- Attachment Point: USD 0
- Limit per Occurrence: USD 100,000,000
- **Annual Aggregate Limit:** USD 300,000,000
- **Annual Aggregate Deductible:** USD 25,000,000 (applies to Fire only)
- Deductible per Occurrence: USD 5,000,000
- Limit per Occurrence: USD 100,000,000
- **Annual Aggregate Deductible:** USD 25,000,000
- **Annual Aggregate Limit:** USD 300,000,000

- **Layer 2:**
- Attachment Point: USD 100,000,000
- Limit per Occurrence: USD 150,000,000
- **Annual Aggregate Limit:** USD 450,000,000
- Attachment Point: USD 105,000,000
- Limit per Occurrence: USD 145,000,000
- **Annual Aggregate Limit:** USD 435,000,000

- **Layer 3:**
- Attachment Point: USD 250,000,000
- Limit per Occurrence: USD 250,000,000
- **Annual Aggregate Limit:** USD 600,000,000
- Attachment Point: USD 250,000,000
- Limit per Occurrence: USD 250,000,000
- **Annual Aggregate Limit:** USD 750,000,000

---

### 2. Natural Catastrophe (Earthquake, Flood, Storm)
### 2. Natural Catastrophe (Windstorm, Earthquake)

- **Layer 1:**
- Attachment Point: USD 0
- Limit per Occurrence: USD 75,000,000
- **Annual Aggregate Limit:** USD 225,000,000
- Deductible per Occurrence: USD 5,000,000
- Limit per Occurrence: USD 100,000,000
- **Annual Aggregate Deductible:** USD 25,000,000
- **Annual Aggregate Limit:** USD 300,000,000

- **Layer 2:**
- Attachment Point: USD 75,000,000
- Limit per Occurrence: USD 125,000,000
- **Annual Aggregate Limit:** USD 375,000,000
- Attachment Point: USD 105,000,000
- Limit per Occurrence: USD 145,000,000
- **Annual Aggregate Limit:** USD 435,000,000

- **Layer 3:**
- Attachment Point: USD 200,000,000
- Limit per Occurrence: USD 200,000,000
- **Annual Aggregate Limit:** USD 500,000,000
- Attachment Point: USD 250,000,000
- Limit per Occurrence: USD 250,000,000
- **Annual Aggregate Limit:** USD 750,000,000

---

### 3. Business Interruption

- **Layer 1:**
- Attachment Point: USD 0
- Limit per Occurrence: USD 50,000,000
- **Annual Aggregate Limit:** USD 150,000,000
- Deductible per Occurrence: USD 5,000,000
- Limit per Occurrence: USD 100,000,000
- **Annual Aggregate Deductible:** USD 25,000,000
- **Annual Aggregate Limit:** USD 300,000,000

- **Layer 2:**
- Attachment Point: USD 50,000,000
- Limit per Occurrence: USD 100,000,000
- **Annual Aggregate Limit:** USD 300,000,000
- Attachment Point: USD 105,000,000
- Limit per Occurrence: USD 145,000,000
- **Annual Aggregate Limit:** USD 435,000,000

- **Layer 3:**
- Attachment Point: USD 150,000,000
- Limit per Occurrence: USD 150,000,000
- **Annual Aggregate Limit:** USD 450,000,000
- Attachment Point: USD 250,000,000
- Limit per Occurrence: USD 250,000,000
- **Annual Aggregate Limit:** USD 750,000,000

---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public static class InsuranceAIExtensions
public static IServiceCollection AddInsuranceAI(this IServiceCollection services)
{
services.AddSingleton<IAgentDefinition, InsuranceAgent>();
services.AddSingleton<IAgentDefinition, RiskImportAgent>();
services.AddSingleton<IAgentDefinition, SlipImportAgent>();

return services;
}
Expand Down
81 changes: 56 additions & 25 deletions modules/Insurance/MeshWeaver.Insurance.AI/InsuranceAgent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ namespace MeshWeaver.Insurance.AI;
/// <summary>
/// Main Insurance agent that provides access to insurance pricing data and collections.
/// </summary>
[DefaultAgent]
public class InsuranceAgent(IMessageHub hub) : IInitializableAgent, IAgentWithPlugins, IAgentWithContext
[ExposedInNavigator]
public class InsuranceAgent(IMessageHub hub) : IInitializableAgent, IAgentWithPlugins, IAgentWithContext, IAgentWithDelegations
{
private Dictionary<string, TypeDescription>? typeDefinitionMap;
private Dictionary<string, LayoutAreaDefinition>? layoutAreaMap;
Expand All @@ -23,34 +23,65 @@ public class InsuranceAgent(IMessageHub hub) : IInitializableAgent, IAgentWithPl
public string Description =>
"Handles all questions and actions related to insurance pricings, property risks, and dimensions. " +
"Provides access to pricing data, allows creation and management of pricings and property risks. " +
"Also manages submission documents and files for each pricing.";
"Also manages submission documents and files for each pricing. " +
"Can delegate to specialized import agents for processing risk data files and slip documents.";

public IEnumerable<DelegationDescription> Delegations
{
get
{
yield return new DelegationDescription(
nameof(RiskImportAgent),
"Delegate to RiskImportAgent when the user wants to import property risks from Excel files, " +
"or when working with risk data files (.xlsx, .xls) that contain property information like " +
"location, TSI (Total Sum Insured), address, country, currency, building values, etc. " +
"Common file names include: risks.xlsx, exposure.xlsx, property schedule, location schedule, etc."
);

yield return new DelegationDescription(
nameof(SlipImportAgent),
"Delegate to SlipImportAgent when the user wants to import insurance slips from PDF documents, " +
"or when working with slip files (.pdf) that contain insurance submission information like " +
"insured details, coverage terms, premium information, reinsurance structure layers, limits, rates, etc. " +
"Common file names include: slip.pdf, submission.pdf, placement.pdf, quote.pdf, etc."
);
}
}

public string Instructions =>
$$$"""
The agent is the InsuranceAgent, specialized in managing insurance pricings:

## Content Collection Context

IMPORTANT: The current context is set to pricing/{pricingId} where pricingId follows the format {company}-{uwy}.
- The submission files collection is named "Submissions-{pricingId}"
- All file paths are relative to the root (/) of this collection
- Example: For pricing "AXA-2024", the collection is "Submissions-AXA-2024" and files are at paths like "/slip.pdf", "/risks.xlsx"

## Working with Submission Documents and Files

CRITICAL: When users ask about submission files, documents, or content:
- DO NOT call {{{nameof(DataPlugin.GetData)}}} for Pricing or any other data first
- DO NOT try to verify the pricing exists before accessing files
- The SubmissionPlugin is already configured for the current pricing context
- Simply call the SubmissionPlugin functions directly

Available SubmissionPlugin functions (all collectionName parameters are optional):
- {{{nameof(ContentCollectionPlugin.ListFiles)}}}() - List all files in the current pricing's submissions
- {{{nameof(ContentCollectionPlugin.ListFolders)}}}() - List all folders
- {{{nameof(ContentCollectionPlugin.ListCollectionItems)}}}() - List both files and folders
- {{{nameof(ContentCollectionPlugin.GetDocument)}}}(documentPath) - Get document content
- {{{nameof(ContentCollectionPlugin.SaveDocument)}}}(documentPath, content) - Save a document
- {{{nameof(ContentCollectionPlugin.DeleteFile)}}}(filePath) - Delete a file
- {{{nameof(ContentCollectionPlugin.CreateFolder)}}}(folderPath) - Create a folder
- {{{nameof(ContentCollectionPlugin.DeleteFolder)}}}(folderPath) - Delete a folder
- The ContentPlugin is already configured for the current pricing context
- Simply call the ContentPlugin functions directly
- All file paths should start with "/" (e.g., "/slip.pdf", "/risks.xlsx")

Available ContentPlugin functions (all collectionName parameters are optional):
- {{{nameof(ContentPlugin.ListFiles)}}}() - List all files in the current pricing's submissions
- {{{nameof(ContentPlugin.ListFolders)}}}() - List all folders
- {{{nameof(ContentPlugin.ListCollectionItems)}}}() - List both files and folders
- {{{nameof(ContentPlugin.GetDocument)}}}(documentPath) - Get document content (use path like "/Slip.md")
- {{{nameof(ContentPlugin.SaveFile)}}}(documentPath, content) - Save a document
- {{{nameof(ContentPlugin.DeleteFile)}}}(filePath) - Delete a file
- {{{nameof(ContentPlugin.CreateFolder)}}}(folderPath) - Create a folder
- {{{nameof(ContentPlugin.DeleteFolder)}}}(folderPath) - Delete a folder

Examples:
- User: "Show me the submission files" → You: Call {{{nameof(ContentCollectionPlugin.ListFiles)}}}()
- User: "What files are in the submissions?" → You: Call {{{nameof(ContentCollectionPlugin.ListFiles)}}}()
- User: "Read the slip document" → You: Call {{{nameof(ContentCollectionPlugin.GetDocument)}}}("Slip.md")
- User: "Show me the submission files" → You: Call {{{nameof(ContentPlugin.ListFiles)}}}()
- User: "What files are in the submissions?" → You: Call {{{nameof(ContentPlugin.ListFiles)}}}()
- User: "Read the slip document" → You: Call {{{nameof(ContentPlugin.GetDocument)}}}("/Slip.md")

## Working with Pricing Data

Expand All @@ -71,14 +102,14 @@ IEnumerable<KernelPlugin> IAgentWithPlugins.GetPlugins(IAgentChat chat)
yield return new DataPlugin(hub, chat, typeDefinitionMap).CreateKernelPlugin();
yield return new LayoutAreaPlugin(hub, chat, layoutAreaMap).CreateKernelPlugin();

// Always provide ContentCollectionPlugin - it will use ContextToConfigMap to determine the collection
var submissionPluginConfig = CreateSubmissionPluginConfig(chat);
yield return new ContentCollectionPlugin(hub, submissionPluginConfig, chat).CreateKernelPlugin();
// Always provide ContentPlugin - it will use ContextToConfigMap to determine the collection
var submissionPluginConfig = CreateSubmissionPluginConfig();
yield return new ContentPlugin(hub, submissionPluginConfig, chat).CreateKernelPlugin();
}

private static ContentCollectionPluginConfig CreateSubmissionPluginConfig(IAgentChat chat)
private static ContentPluginConfig CreateSubmissionPluginConfig()
{
return new ContentCollectionPluginConfig
return new ContentPluginConfig
{
Collections = [],
ContextToConfigMap = context =>
Expand Down Expand Up @@ -118,7 +149,7 @@ async Task IInitializableAgent.InitializeAsync()
var typesResponse = await hub.AwaitResponse(
new GetDomainTypesRequest(),
o => o.WithTarget(new PricingAddress("default")));
typeDefinitionMap = typesResponse.Message.Types.Select(t => t with { Address = null }).ToDictionary(x => x.Name);
typeDefinitionMap = typesResponse?.Message?.Types?.Select(t => t with { Address = null }).ToDictionary(x => x.Name!);
}
catch
{
Expand All @@ -130,7 +161,7 @@ async Task IInitializableAgent.InitializeAsync()
var layoutAreaResponse = await hub.AwaitResponse(
new GetLayoutAreasRequest(),
o => o.WithTarget(new PricingAddress("default")));
layoutAreaMap = layoutAreaResponse.Message.Areas.ToDictionary(x => x.Area);
layoutAreaMap = layoutAreaResponse?.Message?.Areas?.ToDictionary(x => x.Area);
}
catch
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,10 @@
<ProjectReference Include="..\MeshWeaver.Insurance.Domain\MeshWeaver.Insurance.Domain.csproj" />
</ItemGroup>


<ItemGroup>
<PackageReference Include="ClosedXML" />
<PackageReference Include="itext7" />
</ItemGroup>

</Project>
Loading