Repository navigation
The AI application folds into the engine — one assembly, one module, one Store entry (#2276) - #2297
Conversation
…one Store entry `MeshWeaver.AI.Application` becomes `MeshWeaver.AI/Application/`. The namespaces are unchanged (`MeshWeaver.AI.Application`, `…Application.Layout`) because they were already sub-namespaces of the engine; only the assembly boundary goes. Step toward #2276: installing AI must install the app that maintains agents, models, skills and harnesses — one entry in the Store, not two. **The application was DEAD, and nothing said so.** It carried `[assembly: AgentsApplication]`, but a `MeshNodeProviderAttribute` is read in exactly ONE place — `MeshBuilder.InstallAssemblies`, i.e. the `Modules:Assemblies` lane — and that assembly was never listed there. It rode the app closure through a ProjectReference from `MeshWeaver.Blazor.Portal` and shipped in every image contributing nothing: no Agents hub, no agent overview, and its two autocomplete providers registered on a container that was never built. `ThreadChatView` carries the scar — it news up `SkillAutocompleteProvider` by hand, with a comment that resolving it from DI "returned null and typing '/' showed nothing". Both portals now list `MeshWeaver.AI.dll` under `Modules:Assemblies`, so the attribute is read and the application is contributed by the same load that brings the engine. The DLL still rides the app closure, so `ResolveModulePath` falls back to the app folder — the documented thin lane, the same step #1644 used for every module that has since left. **Turning it on surfaced a platform hang, which is fixed here rather than worked around.** `DataExtensions.HandleAutocompleteRequest` took `LastAsync()` — which emits only when the combined stream COMPLETES. A provider backed by mesh data never completes: it is a live subscription by design (`SkillAutocompleteProvider` composes ObserveSkillQueries → ObserveSnapshot → Switch). So on any hub with such a provider the handler ran, returned `Processed` in 27 ms, and posted NOTHING. The caller waited out its timeout against silence. Read straight off the message trace, per the /debug procedure: `HUB_HANDLE_START` → `HUB_HANDLE_END Result: Processed` at +27 ms, then no response post from that hub for the remaining 30 s — a burst of work followed by silence, i.e. a missed observation, not a lock. "Settled" is now a QUIET PERIOD, never completion: first of a 150 ms throttle, a 2 s deadline answering with the best snapshot so far, or a 2.5 s floor answering empty if no provider ever produced anything. A one-shot request must produce exactly one answer — never a hang, which is indistinguishable from "still thinking". The AI application's duplicate handler is deleted with it: the platform's copy has relevance scoring this one never had, and a second registration for one request type is how the two drifted. The round trip that timed out at 30 s now answers in well under a second. Verified: full solution build with CI's flags; `MeshWeaver.Autocomplete.Test` 155/155; `MeshWeaver.Data.Test` 385/385; the new `AgentsApplicationInstallTest` round trip green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR folds the (previously inactive) MeshWeaver.AI.Application into the MeshWeaver.AI engine assembly so installing AI brings along the Agents maintenance application as a single module/Store entry, and fixes the platform autocomplete one-shot handler so it always answers (no more LastAsync() hang on non-completing provider streams).
Changes:
- Moved the Agents application node contribution into
MeshWeaver.AIvia an assembly attribute and removed the separateMeshWeaver.AI.Applicationproject/reference. - Fixed
AutocompleteRequesthandling to respond based on a “settled/quiet”, deadline, or silence-floor policy rather than waiting for stream completion. - Added module-install and round-trip response tests to ensure the Agents app hub is actually built when installed via
Modules:Assemblies.
Reviewed changes
Copilot reviewed 13 out of 16 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| test/MeshWeaver.AI.Test/AgentsApplicationModuleTest.cs | Adds tests asserting the Agents app is contributed by the engine assembly attribute and responds when installed via InstallAssemblies. |
| src/MeshWeaver.Data/DataExtensions.cs | Fixes HandleAutocompleteRequest to always emit one response without requiring stream completion. |
| src/MeshWeaver.Blazor.Portal/MeshWeaver.Blazor.Portal.csproj | Removes the now-obsolete MeshWeaver.AI.Application project reference. |
| src/MeshWeaver.AI/MeshWeaver.AI.csproj | Adds MeshWeaver.Layout reference to support the folded-in application views/areas. |
| src/MeshWeaver.AI/Application/Layout/AgentsApplicationLayoutExtensions.cs | Renames the layout extension class and continues to provide the layout registration entrypoint used by the app configuration. |
| src/MeshWeaver.AI/Application/Layout/AgentDetailsArea.cs | Introduces a new agent-details layout area (includes delegation rendering and navigation). |
| src/MeshWeaver.AI/Application/ApplicationAddress.cs | Introduces a canonical address for the Agents application hub. |
| src/MeshWeaver.AI/Application/AgentsApplicationExtensions.cs | Configures the Agents application hub services (autocomplete providers) without duplicating the platform handler. |
| src/MeshWeaver.AI/Application/AgentsApplicationAttribute.cs | Adds the assembly-level mesh node contribution ([assembly: AgentsApplication]) in the engine assembly. |
| src/MeshWeaver.AI.Application/README.md | Deleted (project removed/folded into engine). |
| src/MeshWeaver.AI.Application/MeshWeaver.AI.Application.csproj | Deleted (project removed/folded into engine). |
| src/MeshWeaver.AI.Application/GlobalUsings.cs | Deleted (project removed/folded into engine). |
| src/MeshWeaver.AI.Application/AgentsApplicationExtensions.cs | Deleted (migrated into MeshWeaver.AI). |
| MeshWeaver.slnx | Removes the MeshWeaver.AI.Application project from the solution. |
| memex/Memex.Portal.Monolith/appsettings.json | Adds MeshWeaver.AI.dll to Modules:Assemblies so the assembly attribute is actually read/applied. |
| memex/aspire/Memex.Portal.Distributed/appsettings.json | Same as monolith: ensures the module lane installs MeshWeaver.AI.dll. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Blocked on Systemorph/MeshWeaver.Plugins#685 — by design, and the gate proved it. The The plugins repo keeps its own copy of Plugins#685 drops it, verified building that project against both core The other red, |
…n build cannot `FrameworkBuildIdentityTest.CanonicalList_MatchesTheTesterClosure` went red: the canonical `FrameworkBuildIdentity.ContentSurfaceAssemblies` list is the surface in-mesh CONTENT may compile against, and it is pinned to the bake host's project closure. Adding `MeshWeaver.Mesh.Operations` puts a new assembly in that closure — through `MeshWeaver.AI`, which the tester references — so the list has to gain it or the two drift. A real finding, not a flake, and worth noting HOW it was found: a full solution build cannot see it (everything compiles either way), and it is the closure of a TOOL rather than of anything the diff names. The gate recomputes the closure from the csproj graph precisely so the list cannot silently fall behind. Also merges origin/main (#2297 landed). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Installing AI must install the app that maintains agents, models, skills and harnesses. One entry in the Store, not two.
MeshWeaver.AI.ApplicationbecomesMeshWeaver.AI/Application/— namespaces unchanged (they were already sub-namespaces of the engine), only the assembly boundary goes.The application was dead code, and nothing said so
It carried
[assembly: AgentsApplication]. But aMeshNodeProviderAttributeis read in exactly one place —MeshBuilder.InstallAssemblies, i.e. theModules:Assemblieslane — and that assembly was never listed there. It rode the app closure through aProjectReferencefromMeshWeaver.Blazor.Portal, so it shipped in every image contributing nothing: no Agents hub, no agent overview, and its two autocomplete providers registered on a container that was never built.ThreadChatViewcarries the scar. It news upSkillAutocompleteProviderby hand, with a comment explaining that resolving it from DI "returned null and typing '/' showed nothing".Both portals now list
MeshWeaver.AI.dllunderModules:Assemblies, so the attribute is read and the application is contributed by the same load that brings the engine. The DLL still rides the app closure, soResolveModulePathfalls back to the app folder — the documented thin lane, the same step #1644 used for every module that has since left.Turning it on surfaced a platform hang
DataExtensions.HandleAutocompleteRequesttookLastAsync()— which emits only when the combined stream completes. A provider backed by mesh data never completes: it is a live subscription by design (SkillAutocompleteProvidercomposesObserveSkillQueries→ObserveSnapshot→Switch). So on any hub with such a provider registered, the handler ran, returnedProcessedin 27 ms, and posted nothing. The caller waited out its timeout against silence — no error, nothing to grep.Read straight off the message trace, per the
/debugprocedure:A burst of work then total silence — a missed observation, not a lock.
"Settled" is now a quiet period, never completion. First of three wins: a 150 ms throttle; a 2 s deadline answering with the best snapshot so far; a 2.5 s floor answering empty if no provider ever produced anything. A one-shot request must produce exactly one answer — a hang is indistinguishable from "still thinking". One shared
RefCountsubscription, so the providers' queries are not issued twice.The AI application's duplicate handler is deleted with it: the platform's copy has relevance scoring this one never had, and a second registration for one request type is how the two drifted.
The round trip that timed out at 30 s now answers in well under a second.
Verification
0 Error(s).MeshWeaver.Autocomplete.Test— 155/155.MeshWeaver.Data.Test— 385/385.AgentsApplicationModuleTest(the attribute travels with the engine and names the app) andAgentsApplicationInstallTest(installing the assembly the wayModules:Assembliesdoes builds the hub and it answers). The second one failed before the handler fix, which is what makes it a gate rather than a formality.What this sets up
MeshWeaver.AIis now a single assembly carrying the engine and its maintenance application, activated through the module lane. That is the shape a Store package needs: onecontent.module, one entry,Modules:Requiredonce it ships from the registry.Refs #2276
🤖 Generated with Claude Code