Drop ephemeral sessions; refactor agent lifecycle around RunAsync + bus-driven stop #93

Merged
jasoncouture merged 5 commits from claude-is-a-moron into main 2026-05-18 23:49:13 -04:00
jasoncouture commented 2026-05-18 23:49:01 -04:00 (Migrated from github.com)

Summary

  • Drops the parallel EphemeralSession/EphemeralSessionFactory/SessionReplyTool machinery; sessions are unified back into Agent.
  • SessionId carries an auto-generated v7 Guid so the same agent can have multiple distinct boots; DataKey/DefaultSessionName/IsDefault move onto the record.
  • IAgent.RunAsync replaces the start-then-loop split; agent shutdown is now triggered by command:agent-stop events with agent:starting/started/stopping/stopped lifecycle notifications.
  • AgentManager keeps lifecycle and the loaded-handle dictionary; the blank-EC + scoped DI + data-context boot moves into AgentFactory behind IAgentFactory. AgentHandle owns child sub-handles. ExecuteAsync drains every handle via Command.AgentStop broadcast before disposing.

Test plan

  • dotnet build clean
  • dotnet test clean (unit + integration)
  • manual: heartbeat / cron path exercised against the refactored agent loop

🤖 Generated with Claude Code

## Summary - Drops the parallel `EphemeralSession`/`EphemeralSessionFactory`/`SessionReplyTool` machinery; sessions are unified back into `Agent`. - `SessionId` carries an auto-generated v7 `Guid` so the same agent can have multiple distinct boots; `DataKey`/`DefaultSessionName`/`IsDefault` move onto the record. - `IAgent.RunAsync` replaces the start-then-loop split; agent shutdown is now triggered by `command:agent-stop` events with `agent:starting/started/stopping/stopped` lifecycle notifications. - `AgentManager` keeps lifecycle and the loaded-handle dictionary; the blank-EC + scoped DI + data-context boot moves into `AgentFactory` behind `IAgentFactory`. `AgentHandle` owns child sub-handles. `ExecuteAsync` drains every handle via `Command.AgentStop` broadcast before disposing. ## Test plan - [x] `dotnet build` clean - [x] `dotnet test` clean (unit + integration) - [ ] manual: heartbeat / cron path exercised against the refactored agent loop 🤖 Generated with [Claude Code](https://claude.com/claude-code)
github-actions[bot] commented 2026-05-18 23:50:44 -04:00 (Migrated from github.com)
Package Line Rate Branch Rate Complexity Health
LlamaShears.Core.Eventing 91% 84% 53
LlamaShears.Core.Abstractions 49% 33% 380
LlamaShears.Api 30% 30% 469
LlamaShears.Provider.Ollama 44% 28% 188
LlamaShears.Core.Eventing.Extensions 100% 100% 1
LlamaShears.Core 44% 40% 1444
LlamaShears.Provider.Onnx.Embeddings 37% 38% 72
LlamaShears.Provider.OpenAI 66% 65% 229
LlamaShears.Api.Web 1% 1% 428
LlamaShears.Hosting 33% 21% 27
LlamaShears.Plugins 0% 100% 1
LlamaShears.Core.Eventing 89% 75% 53
LlamaShears 52% 36% 25
LlamaShears.Plugins.Host 34% 24% 36
LlamaShears.Core.Abstractions 34% 15% 380
LlamaShears.Api 6% 1% 469
LlamaShears.Provider.Ollama 3% 1% 188
LlamaShears.Core.Eventing.Extensions 100% 100% 1
StrangeSoft.Plugins.Host 20% 21% 87
LlamaShears.Core 43% 28% 1444
LlamaShears.Provider.Onnx.Embeddings 3% 0% 72
LlamaShears.Provider.OpenAI 2% 0% 229
LlamaShears.Api.Web 21% 10% 428
LlamaShears.Hosting 26% 8% 27
LlamaShears.Plugins 0% 100% 1
LlamaShears.Core.Eventing 89% 75% 53
LlamaShears 52% 36% 25
LlamaShears.Plugins.Host 34% 24% 36
LlamaShears.Core.Abstractions 34% 15% 380
LlamaShears.IntegrationTests 82% 69% 72
LlamaShears.Api 8% 3% 469
LlamaShears.Provider.Ollama 3% 1% 188
LlamaShears.Core.Eventing.Extensions 100% 100% 1
StrangeSoft.Plugins.Host 20% 21% 87
LlamaShears.Core 43% 29% 1444
LlamaShears.Provider.Onnx.Embeddings 3% 0% 72
LlamaShears.Provider.OpenAI 2% 0% 229
LlamaShears.Api.Web 31% 17% 428
LlamaShears.Hosting 26% 8% 27
LlamaShears.Analyzers.CodeFixes 85% 69% 60
LlamaShears.Analyzers 88% 76% 199
Summary 47% (11380 / 33101) 36% (2384 / 9611) 10502
Package | Line Rate | Branch Rate | Complexity | Health -------- | --------- | ----------- | ---------- | ------ LlamaShears.Core.Eventing | 91% | 84% | 53 | ✔ LlamaShears.Core.Abstractions | 49% | 33% | 380 | ❌ LlamaShears.Api | 30% | 30% | 469 | ❌ LlamaShears.Provider.Ollama | 44% | 28% | 188 | ❌ LlamaShears.Core.Eventing.Extensions | 100% | 100% | 1 | ✔ LlamaShears.Core | 44% | 40% | 1444 | ❌ LlamaShears.Provider.Onnx.Embeddings | 37% | 38% | 72 | ❌ LlamaShears.Provider.OpenAI | 66% | 65% | 229 | ➖ LlamaShears.Api.Web | 1% | 1% | 428 | ❌ LlamaShears.Hosting | 33% | 21% | 27 | ❌ LlamaShears.Plugins | 0% | 100% | 1 | ❌ LlamaShears.Core.Eventing | 89% | 75% | 53 | ✔ LlamaShears | 52% | 36% | 25 | ➖ LlamaShears.Plugins.Host | 34% | 24% | 36 | ❌ LlamaShears.Core.Abstractions | 34% | 15% | 380 | ❌ LlamaShears.Api | 6% | 1% | 469 | ❌ LlamaShears.Provider.Ollama | 3% | 1% | 188 | ❌ LlamaShears.Core.Eventing.Extensions | 100% | 100% | 1 | ✔ StrangeSoft.Plugins.Host | 20% | 21% | 87 | ❌ LlamaShears.Core | 43% | 28% | 1444 | ❌ LlamaShears.Provider.Onnx.Embeddings | 3% | 0% | 72 | ❌ LlamaShears.Provider.OpenAI | 2% | 0% | 229 | ❌ LlamaShears.Api.Web | 21% | 10% | 428 | ❌ LlamaShears.Hosting | 26% | 8% | 27 | ❌ LlamaShears.Plugins | 0% | 100% | 1 | ❌ LlamaShears.Core.Eventing | 89% | 75% | 53 | ✔ LlamaShears | 52% | 36% | 25 | ➖ LlamaShears.Plugins.Host | 34% | 24% | 36 | ❌ LlamaShears.Core.Abstractions | 34% | 15% | 380 | ❌ LlamaShears.IntegrationTests | 82% | 69% | 72 | ✔ LlamaShears.Api | 8% | 3% | 469 | ❌ LlamaShears.Provider.Ollama | 3% | 1% | 188 | ❌ LlamaShears.Core.Eventing.Extensions | 100% | 100% | 1 | ✔ StrangeSoft.Plugins.Host | 20% | 21% | 87 | ❌ LlamaShears.Core | 43% | 29% | 1444 | ❌ LlamaShears.Provider.Onnx.Embeddings | 3% | 0% | 72 | ❌ LlamaShears.Provider.OpenAI | 2% | 0% | 229 | ❌ LlamaShears.Api.Web | 31% | 17% | 428 | ❌ LlamaShears.Hosting | 26% | 8% | 27 | ❌ LlamaShears.Analyzers.CodeFixes | 85% | 69% | 60 | ✔ LlamaShears.Analyzers | 88% | 76% | 199 | ✔ **Summary** | **47%** (11380 / 33101) | **36%** (2384 / 9611) | **10502** | ❌ <!-- Sticky Pull Request Commentcoverage -->
copilot-pull-request-reviewer[bot] (Migrated from github.com) reviewed 2026-05-18 23:54:43 -04:00
copilot-pull-request-reviewer[bot] (Migrated from github.com) left a comment

Pull request overview

This PR removes the separate ephemeral-session runtime and refactors agent lifecycle around IAgent.RunAsync, AgentFactory, AgentHandle, and bus-driven command:agent-stop shutdown events.

Changes:

  • Removes ephemeral session abstractions, implementation, MCP session_reply tool, docs, and tests.
  • Adds session-aware lifecycle payloads/events and refactors Agent, AgentManager, and DI registration around AgentFactory.
  • Updates unit test helpers and generated API docs for the new lifecycle/session APIs.

Reviewed changes

Copilot reviewed 52 out of 52 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
tests/LlamaShears.UnitTests/Sessions/EphemeralSessionTests.cs Removes ephemeral session tests.
tests/LlamaShears.UnitTests/Agent/Core/TestAgentConfigs.cs Seeds test data scopes with SessionId.
tests/LlamaShears.UnitTests/Agent/Core/AgentTurnFlowTests.cs Switches test agent startup to RunAsync.
tests/LlamaShears.UnitTests/Agent/Core/AgentLoopTests.cs Switches test agent startup to RunAsync.
tests/LlamaShears.UnitTests/Agent/Core/AgentInterruptTests.cs Switches test agent startup to RunAsync.
tests/LlamaShears.UnitTests/Agent/Core/AgentInterruptGracefulTests.cs Switches test agent startup to RunAsync.
tests/LlamaShears.UnitTests/Agent/Core/AgentEventPublishingTests.cs Switches event publishing test startup to RunAsync.
src/public/LlamaShears.Core.Abstractions/Events/Event.cs Adds agent lifecycle and stop command event types.
src/public/LlamaShears.Core.Abstractions/Events/Agent/AgentStopRequest.cs Adds stop request payload.
src/public/LlamaShears.Core.Abstractions/Events/Agent/AgentLoadRequest.cs Adds session namespace import.
src/public/LlamaShears.Core.Abstractions/Events/Agent/AgentEventInformation.cs Adds lifecycle event payload.
src/public/LlamaShears.Core.Abstractions/Agent/Sessions/SessionId.cs Adds boot GUID, session constants, and updated parse/string format.
src/public/LlamaShears.Core.Abstractions/Agent/Sessions/SessionExtensions.cs Adds data-scope session accessors.
src/public/LlamaShears.Core.Abstractions/Agent/Sessions/IEphemeralSessionFactory.cs Removes ephemeral session factory API.
src/public/LlamaShears.Core.Abstractions/Agent/Sessions/IEphemeralSession.cs Removes ephemeral session API.
src/public/LlamaShears.Core.Abstractions/Agent/Sessions/EphemeralSessionRequest.cs Removes ephemeral request type.
src/public/LlamaShears.Core.Abstractions/Agent/Sessions/EphemeralSessionReference.cs Removes ephemeral reference type.
src/public/LlamaShears.Core.Abstractions/Agent/Sessions/EphemeralSessionContext.cs Removes ephemeral context type.
src/public/LlamaShears.Core.Abstractions/Agent/Sessions/EphemeralRunResult.cs Removes ephemeral run result type.
src/public/LlamaShears.Core.Abstractions/Agent/IAgent.cs Replaces StartAsync with RunAsync.
src/public/LlamaShears.Core.Abstractions/Agent/AgentConfigExtensions.cs Adds trailing whitespace-only change.
src/LlamaShears.Core/Sessions/EphemeralSessionFactory.cs Removes ephemeral session factory implementation.
src/LlamaShears.Core/Sessions/EphemeralSession.cs Removes ephemeral session implementation.
src/LlamaShears.Core/IAgentFactory.cs Adds agent factory abstraction.
src/LlamaShears.Core/CoreServiceCollectionExtensions.cs Registers IAgentFactory and removes ephemeral factory registration.
src/LlamaShears.Core/AgentManager.cs Refactors loaded handles and shutdown lifecycle.
src/LlamaShears.Core/AgentHandle.cs Adds handle ownership and child disposal support.
src/LlamaShears.Core/AgentFactory.cs Adds scoped agent bootstrapping.
src/LlamaShears.Core/Agent.cs Refactors agent loop, lifecycle events, and stop handling.
src/LlamaShears.Api/Tools/ModelContextProtocol/Session/SessionReplyTool.cs Removes MCP session reply tool.
src/LlamaShears.Api/Tools/ModelContextProtocol/Session/SessionReplyResult.cs Removes session reply result type.
src/LlamaShears.Api/Tools/ModelContextProtocol/ModelContextProtocolServiceCollectionExtensions.cs Removes session reply tool registration.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Events/Event/WellKnown/Command.md Documents AgentStop.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Events/Event/WellKnown/Agent.md Documents new lifecycle events.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Events/Agent/index.md Adds lifecycle/stop payload docs links.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Events/Agent/AgentStopRequest.md Adds stop request docs.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Events/Agent/AgentEventInformation.md Adds lifecycle payload docs.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/SessionId.md Updates session id docs.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/SessionExtensions/index.md Adds generated extension docs index.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/SessionExtensions/<G>$1E5D4A79A014BD10CBE0F98F7F208BE1/index.md Adds generated extension backing docs.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/SessionExtensions/<G>$1E5D4A79A014BD10CBE0F98F7F208BE1/<M>$4CE8FFD1231E591D45179C9C504A5A71.md Adds generated extension method backing docs.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/SessionExtensions/<G>$1E5D4A79A014BD10CBE0F98F7F208BE1.md Adds generated extension backing type docs.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/SessionExtensions.md Adds public session extension docs.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/index.md Removes ephemeral docs links and adds session extensions.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/IEphemeralSessionFactory.md Removes ephemeral factory docs.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/IEphemeralSession.md Removes ephemeral session docs.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/EphemeralSessionRequest.md Removes ephemeral request docs.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/EphemeralSessionReference.md Removes ephemeral reference docs.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/EphemeralSessionContext.md Removes ephemeral context docs.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/EphemeralRunResult.md Removes ephemeral run result docs.
docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/IAgent.md Updates agent API docs for RunAsync.
docs/api/LlamaShears.Core.Abstractions/index.md Updates root API index for removed/added types.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

## Pull request overview This PR removes the separate ephemeral-session runtime and refactors agent lifecycle around `IAgent.RunAsync`, `AgentFactory`, `AgentHandle`, and bus-driven `command:agent-stop` shutdown events. **Changes:** - Removes ephemeral session abstractions, implementation, MCP `session_reply` tool, docs, and tests. - Adds session-aware lifecycle payloads/events and refactors `Agent`, `AgentManager`, and DI registration around `AgentFactory`. - Updates unit test helpers and generated API docs for the new lifecycle/session APIs. ### Reviewed changes Copilot reviewed 52 out of 52 changed files in this pull request and generated 15 comments. <details> <summary>Show a summary per file</summary> | File | Description | | ---- | ----------- | | tests/LlamaShears.UnitTests/Sessions/EphemeralSessionTests.cs | Removes ephemeral session tests. | | tests/LlamaShears.UnitTests/Agent/Core/TestAgentConfigs.cs | Seeds test data scopes with `SessionId`. | | tests/LlamaShears.UnitTests/Agent/Core/AgentTurnFlowTests.cs | Switches test agent startup to `RunAsync`. | | tests/LlamaShears.UnitTests/Agent/Core/AgentLoopTests.cs | Switches test agent startup to `RunAsync`. | | tests/LlamaShears.UnitTests/Agent/Core/AgentInterruptTests.cs | Switches test agent startup to `RunAsync`. | | tests/LlamaShears.UnitTests/Agent/Core/AgentInterruptGracefulTests.cs | Switches test agent startup to `RunAsync`. | | tests/LlamaShears.UnitTests/Agent/Core/AgentEventPublishingTests.cs | Switches event publishing test startup to `RunAsync`. | | src/public/LlamaShears.Core.Abstractions/Events/Event.cs | Adds agent lifecycle and stop command event types. | | src/public/LlamaShears.Core.Abstractions/Events/Agent/AgentStopRequest.cs | Adds stop request payload. | | src/public/LlamaShears.Core.Abstractions/Events/Agent/AgentLoadRequest.cs | Adds session namespace import. | | src/public/LlamaShears.Core.Abstractions/Events/Agent/AgentEventInformation.cs | Adds lifecycle event payload. | | src/public/LlamaShears.Core.Abstractions/Agent/Sessions/SessionId.cs | Adds boot GUID, session constants, and updated parse/string format. | | src/public/LlamaShears.Core.Abstractions/Agent/Sessions/SessionExtensions.cs | Adds data-scope session accessors. | | src/public/LlamaShears.Core.Abstractions/Agent/Sessions/IEphemeralSessionFactory.cs | Removes ephemeral session factory API. | | src/public/LlamaShears.Core.Abstractions/Agent/Sessions/IEphemeralSession.cs | Removes ephemeral session API. | | src/public/LlamaShears.Core.Abstractions/Agent/Sessions/EphemeralSessionRequest.cs | Removes ephemeral request type. | | src/public/LlamaShears.Core.Abstractions/Agent/Sessions/EphemeralSessionReference.cs | Removes ephemeral reference type. | | src/public/LlamaShears.Core.Abstractions/Agent/Sessions/EphemeralSessionContext.cs | Removes ephemeral context type. | | src/public/LlamaShears.Core.Abstractions/Agent/Sessions/EphemeralRunResult.cs | Removes ephemeral run result type. | | src/public/LlamaShears.Core.Abstractions/Agent/IAgent.cs | Replaces `StartAsync` with `RunAsync`. | | src/public/LlamaShears.Core.Abstractions/Agent/AgentConfigExtensions.cs | Adds trailing whitespace-only change. | | src/LlamaShears.Core/Sessions/EphemeralSessionFactory.cs | Removes ephemeral session factory implementation. | | src/LlamaShears.Core/Sessions/EphemeralSession.cs | Removes ephemeral session implementation. | | src/LlamaShears.Core/IAgentFactory.cs | Adds agent factory abstraction. | | src/LlamaShears.Core/CoreServiceCollectionExtensions.cs | Registers `IAgentFactory` and removes ephemeral factory registration. | | src/LlamaShears.Core/AgentManager.cs | Refactors loaded handles and shutdown lifecycle. | | src/LlamaShears.Core/AgentHandle.cs | Adds handle ownership and child disposal support. | | src/LlamaShears.Core/AgentFactory.cs | Adds scoped agent bootstrapping. | | src/LlamaShears.Core/Agent.cs | Refactors agent loop, lifecycle events, and stop handling. | | src/LlamaShears.Api/Tools/ModelContextProtocol/Session/SessionReplyTool.cs | Removes MCP session reply tool. | | src/LlamaShears.Api/Tools/ModelContextProtocol/Session/SessionReplyResult.cs | Removes session reply result type. | | src/LlamaShears.Api/Tools/ModelContextProtocol/ModelContextProtocolServiceCollectionExtensions.cs | Removes session reply tool registration. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Events/Event/WellKnown/Command.md | Documents `AgentStop`. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Events/Event/WellKnown/Agent.md | Documents new lifecycle events. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Events/Agent/index.md | Adds lifecycle/stop payload docs links. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Events/Agent/AgentStopRequest.md | Adds stop request docs. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Events/Agent/AgentEventInformation.md | Adds lifecycle payload docs. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/SessionId.md | Updates session id docs. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/SessionExtensions/index.md | Adds generated extension docs index. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/SessionExtensions/\<G>$1E5D4A79A014BD10CBE0F98F7F208BE1/index.md | Adds generated extension backing docs. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/SessionExtensions/\<G>$1E5D4A79A014BD10CBE0F98F7F208BE1/\<M>$4CE8FFD1231E591D45179C9C504A5A71.md | Adds generated extension method backing docs. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/SessionExtensions/\<G>$1E5D4A79A014BD10CBE0F98F7F208BE1.md | Adds generated extension backing type docs. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/SessionExtensions.md | Adds public session extension docs. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/index.md | Removes ephemeral docs links and adds session extensions. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/IEphemeralSessionFactory.md | Removes ephemeral factory docs. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/IEphemeralSession.md | Removes ephemeral session docs. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/EphemeralSessionRequest.md | Removes ephemeral request docs. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/EphemeralSessionReference.md | Removes ephemeral reference docs. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/EphemeralSessionContext.md | Removes ephemeral context docs. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/Sessions/EphemeralRunResult.md | Removes ephemeral run result docs. | | docs/api/LlamaShears.Core.Abstractions/LlamaShears/Core/Abstractions/Agent/IAgent.md | Updates agent API docs for `RunAsync`. | | docs/api/LlamaShears.Core.Abstractions/index.md | Updates root API index for removed/added types. | </details> --- 💡 <a href="/jasoncouture/llama-shears/new/main?filename=.github/instructions/*.instructions.md" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Add Copilot custom instructions</a> for smarter, more guided reviews. <a href="https://docs.github.com/en/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot" class="Link--inTextBlock" target="_blank" rel="noopener noreferrer">Learn how to get started</a>.
@ -0,0 +7,4 @@
## Types
- [<G>$1E5D4A79A014BD10CBE0F98F7F208BE1](<G>$1E5D4A79A014BD10CBE0F98F7F208BE1.md)
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-18 23:54:42 -04:00

These generated documentation pages expose compiler-generated extension-block names (<G>$..., <M>$...) instead of the public SessionExtensions.GetSessionId/TryGetSessionId API. Publishing these links makes the API docs hard to use and exposes implementation artifacts; the docs generation should suppress extension-block backing types or flatten the methods under SessionExtensions.

These generated documentation pages expose compiler-generated extension-block names (`<G>$...`, `<M>$...`) instead of the public `SessionExtensions.GetSessionId`/`TryGetSessionId` API. Publishing these links makes the API docs hard to use and exposes implementation artifacts; the docs generation should suppress extension-block backing types or flatten the methods under `SessionExtensions`.
@ -111,1 +148,4 @@
public async ValueTask HandleAsync(IEventEnvelope<AgentStopRequest> envelope, CancellationToken cancellationToken)
{
if (_shutdown.IsCancellationRequested) return;
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-18 23:54:40 -04:00

This opens the default/root context regardless of the active SessionId, so non-default boots will read and drive the main transcript instead of their own isolated session transcript. Use the session id from the data scope when opening the context so child/sub-session runs don't share or corrupt the default conversation history.

This opens the default/root context regardless of the active `SessionId`, so non-default boots will read and drive the main transcript instead of their own isolated session transcript. Use the session id from the data scope when opening the context so child/sub-session runs don't share or corrupt the default conversation history.
@ -112,0 +155,4 @@
if (envelope.Data.SessionId != ownSessionId)
{
return;
}
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-18 23:54:43 -04:00

RunAsync no longer enforces the previous single-start invariant. Calling it twice on the same Agent will open another context/loop over the same subscriptions and queue, leading to competing consumers and duplicate lifecycle/service starts; keep an interlocked/idempotency guard even with the new RunAsync lifecycle.

`RunAsync` no longer enforces the previous single-start invariant. Calling it twice on the same `Agent` will open another context/loop over the same subscriptions and queue, leading to competing consumers and duplicate lifecycle/service starts; keep an interlocked/idempotency guard even with the new RunAsync lifecycle.
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-18 23:54:41 -04:00

The awaited agent-stop handler only cancels the loop and returns; it does not wait for _loopStatus, so callers awaiting PublishAsync(command:agent-stop, ...) can observe completion before stopping/stopped have been published and before agent services have drained. This contradicts the new stop contract and makes bus-driven shutdown races likely.

The awaited `agent-stop` handler only cancels the loop and returns; it does not wait for `_loopStatus`, so callers awaiting `PublishAsync(command:agent-stop, ...)` can observe completion before `stopping/stopped` have been published and before agent services have drained. This contradicts the new stop contract and makes bus-driven shutdown races likely.
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-18 23:54:43 -04:00

ShutdownLoopAsync treats _started == false as “no loop to wait for,” but RunAsync sets _started only after opening the context and publishing starting. If disposal/stop races during that startup window, _loopStatus is completed early and the scope can be disposed while RunAsync is still executing startup code.

`ShutdownLoopAsync` treats `_started == false` as “no loop to wait for,” but `RunAsync` sets `_started` only after opening the context and publishing `starting`. If disposal/stop races during that startup window, `_loopStatus` is completed early and the scope can be disposed while `RunAsync` is still executing startup code.
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-18 23:54:41 -04:00

PublishLifecycleEventAsync now sends AgentEventInformation for agent:idle and agent:busy, but existing subscribers such as CompactionAgentService subscribe to those lifecycle events with AgentLifecycleMarker. Because the event bus dispatches by payload type, idle/busy subscribers will no longer receive these events, so idle compaction will stop running.

`PublishLifecycleEventAsync` now sends `AgentEventInformation` for `agent:idle` and `agent:busy`, but existing subscribers such as `CompactionAgentService` subscribe to those lifecycle events with `AgentLifecycleMarker`. Because the event bus dispatches by payload type, idle/busy subscribers will no longer receive these events, so idle compaction will stop running.
@ -0,0 +38,4 @@
globals[pair.Key] = pair.Value;
}
// These are authoratative, not to be overwriten by the caller.
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-18 23:54:42 -04:00

Correct the typos in this comment: “authoratative” should be “authoritative” and “overwriten” should be “overwritten”.

Correct the typos in this comment: “authoratative” should be “authoritative” and “overwriten” should be “overwritten”.
@ -0,0 +41,4 @@
// These are authoratative, not to be overwriten by the caller.
globals[AgentConfig.DataKey] = config;
globals[ModelConfiguration.DataKey] = config.Model;
globals[SessionId.DataKey] = session;
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-18 23:54:42 -04:00

The implementation applies caller-supplied data first and then overwrites AgentConfig, ModelConfiguration, and SessionId, while the public IAgentFactory contract says caller data overlays the defaults and “caller wins.” This mismatch will surprise callers that rely on the documented overlay behavior; either the implementation or the public contract should be changed to match.

The implementation applies caller-supplied `data` first and then overwrites `AgentConfig`, `ModelConfiguration`, and `SessionId`, while the public `IAgentFactory` contract says caller data overlays the defaults and “caller wins.” This mismatch will surprise callers that rely on the documented overlay behavior; either the implementation or the public contract should be changed to match.
@ -0,0 +49,4 @@
var dataContextFactory = scope.ServiceProvider.GetRequiredService<IDataContextFactory>();
dataContextFactory.CreateContext(config.Id);
var dataProviders = scope.ServiceProvider.GetScopedDataProviders();
await dataContextFactory.InitializeAsync(config.Id, dataProviders, globals, cancellationToken);
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-18 23:54:40 -04:00

The data context is still keyed only by config.Id, so starting a second boot/session for the same agent will hit DataContextFactory.CreateContext's duplicate-key check and fail. Since the factory now accepts a SessionId specifically to support distinct boots, the context key needs to include the session identity (and corresponding cleanup must use the same key).

The data context is still keyed only by `config.Id`, so starting a second boot/session for the same agent will hit `DataContextFactory.CreateContext`'s duplicate-key check and fail. Since the factory now accepts a `SessionId` specifically to support distinct boots, the context key needs to include the session identity (and corresponding cleanup must use the same key).
@ -0,0 +53,4 @@
_ = scope.ServiceProvider.GetRequiredService<ILanguageModel>();
var agent = scope.ServiceProvider.GetRequiredService<IAgent>();
var runTask = agent.RunAsync();
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-18 23:54:40 -04:00

StartAgentAsync returns immediately after calling agent.RunAsync() without awaiting any startup milestone or checking whether the returned task has already faulted. Because exceptions from RunAsync are captured on the task, failures opening the context, publishing starting, or starting agent services can still produce an AgentHandle that the manager records as loaded even though the agent loop is dead.

`StartAgentAsync` returns immediately after calling `agent.RunAsync()` without awaiting any startup milestone or checking whether the returned task has already faulted. Because exceptions from `RunAsync` are captured on the task, failures opening the context, publishing `starting`, or starting agent services can still produce an `AgentHandle` that the manager records as loaded even though the agent loop is dead.
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-18 23:54:43 -04:00

This snapshots _loaded.Keys from a plain Dictionary without holding _mutex, while load/unload handlers can mutate the same dictionary under the mutex. During shutdown a concurrent load/unload can throw or produce inconsistent draining; take the snapshot while holding the mutex (or use a concurrent collection consistently).

This snapshots `_loaded.Keys` from a plain `Dictionary` without holding `_mutex`, while load/unload handlers can mutate the same dictionary under the mutex. During shutdown a concurrent load/unload can throw or produce inconsistent draining; take the snapshot while holding the mutex (or use a concurrent collection consistently).
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-18 23:54:41 -04:00

This ContinueWith uses an async delegate, which produces a nested Task<Task>. The list stores the outer task, so Task.WhenAll(tasks) can complete before localHandle.DisposeAsync() has finished, allowing host shutdown to exit without actually draining/disposal of the handles. Use an async helper or unwrap/await the inner task.

This `ContinueWith` uses an `async` delegate, which produces a nested `Task<Task>`. The list stores the outer task, so `Task.WhenAll(tasks)` can complete before `localHandle.DisposeAsync()` has finished, allowing host shutdown to exit without actually draining/disposal of the handles. Use an async helper or unwrap/await the inner task.
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-18 23:54:41 -04:00

This log records handle.Id.Name, which is the session name (for the default boot, "default") rather than the agent id being stopped. Stop logs will therefore say Stopped agent 'default' for every default session, making operational diagnostics misleading.

This log records `handle.Id.Name`, which is the session name (for the default boot, "default") rather than the agent id being stopped. Stop logs will therefore say `Stopped agent 'default'` for every default session, making operational diagnostics misleading.
@ -12,9 +12,12 @@ namespace LlamaShears.Core.Abstractions.Agent.Sessions;
/// e.g. <c>telegram:123456</c>, round-trip cleanly).
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-18 23:54:42 -04:00

The XML docs still describe the canonical form as agentId:defaultChannel and say everything after the first colon is the channel/name, but ToString and TryParse now require agentId:{guid}:name. Public docs for SessionId need to be updated so consumers don't generate identifiers that can no longer parse.

The XML docs still describe the canonical form as `agentId:defaultChannel` and say everything after the first colon is the channel/name, but `ToString` and `TryParse` now require `agentId:{guid}:name`. Public docs for `SessionId` need to be updated so consumers don't generate identifiers that can no longer parse.
@ -65,0 +69,4 @@
/// <summary>Agent shutdown is beginning — children are being disposed before the agent's own scope tears down.</summary>
public static EventType Stopping {get;} = new EventType(Sources.Agent, "stopping");
/// <summary>Agent shutdown is complete — scope disposed, data context deleted.</summary>
public static EventType Stopped {get;} = new EventType(Sources.Agent, "stopped");
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-18 23:54:42 -04:00

These property accessors don't follow the spacing used by the surrounding well-known event declarations ({ get; }). Keeping the same formatting here avoids churn in the public API definitions.

These property accessors don't follow the spacing used by the surrounding well-known event declarations (`{ get; }`). Keeping the same formatting here avoids churn in the public API definitions.
Sign in to join this conversation.
No description provided.