feat(cron): add cron tool surface with stub execution and global json store #36

Merged
jasoncouture merged 4 commits from feat/cron-tool-stub into main 2026-05-07 14:57:22 -04:00
jasoncouture commented 2026-05-07 11:23:59 -04:00 (Migrated from github.com)

Summary

Five MCP tools — cron_schedule / cron_list / cron_cancel / cron_edit / cron_trigger — let an agent register, manage, and manually fire its own cron jobs. Jobs persist to a single global cron.json under PathKind.Data. The execution path is intentionally a stub today: when a job's NextFireAt elapses (or cron_trigger is called), the scheduler logs the would-have-been agent input and recomputes NextFireAt. The single site to upgrade when fires graduate from stub to real is CronScheduler.FireSingleAsync.

Closes the Cron tool item under TASKS.md → "Agent orchestration & context".

What's in here

src/LlamaShears.Core/Cron/

  • CronJob (record) + CronJobEdit (record) — domain types.
  • ICronStore + JsonCronStore — single-file persistence. SemaphoreSlim serialises mutations; saves are atomic (write to cron.json.tmp, then File.Move(..., overwrite: true)). Corrupt JSON on load logs and starts empty rather than refusing to boot.
  • ICronScheduler + CronScheduler — Cronos expression parsing, agent scoping (every public mutation refuses cross-agent reads/writes), and the stub fire path.
  • CronExecutor : BackgroundService — wakes on CronOptions.TickInterval (default 30s) and asks the scheduler to fire any due jobs.
  • CronOptionsFileName (default cron.json), TickInterval (default 30s).
  • CronServiceCollectionExtensions.AddCron() — wires store + scheduler + executor; called from AddCore.

src/LlamaShears.Api/Tools/ModelContextProtocol/Cron/

Five [McpServerToolType] classes, one tool method each, mirroring the existing memory/filesystem tool layout:

  • cron_schedule(name, cronExpression, prompt)
  • cron_list()
  • cron_cancel(id)
  • cron_edit(id, name?, cronExpression?, prompt?, enabled?)
  • cron_trigger(id) — manual fire via the same FireSingleAsync path the executor uses

All tools resolve the calling agent through IAgentWorkspaceLocator (same pattern as the memory tools). Refused: missing agent on the request, malformed GUID, unparseable cron expression.

Storage

Anchored on IShearsPaths.GetPath(PathKind.Data, ensureExists: true). Single global file, by spec — there is one cron store regardless of how many agents are configured. Agent scoping is enforced at the scheduler boundary.

Cron expression library

Cronos 0.10.0, MIT-licensed. Default 5-field form (minute, hour, day-of-month, month, day-of-week), evaluated in UTC.

Tests

13 new TUnit cases under tests/LlamaShears.UnitTests/Cron/:

  • JsonCronStoreTests — fresh-empty, upsert round-trip across instances, upsert-replaces-by-id, remove idempotence, garbage JSON loads empty.
  • CronSchedulerTests — schedule computes next fire, schedule rejects unparseable expression, list is agent-scoped, cancel refuses other-agent jobs, edit patches only provided fields, edit recomputes next fire when expression changes, trigger updates last/next, fire-due skips disabled and not-yet-due jobs.

FakeTimeProvider (Microsoft.Extensions.TimeProvider.Testing) drives the time-sensitive cases; JsonCronStore is exercised against a real tempdir per test for round-trip realism.

Test plan

  • dotnet test --solution LlamaShears.slnx — all 382 passing (was 369 before this PR).
  • Husky dotnet-test-on-source-change pre-commit check passed.
  • Husky docs-api-up-to-date pre-push check passed.
  • No XML doc warnings (concrete types follow ADR-0012; only the two interfaces — ICronStore, ICronScheduler — carry doc comments).

Stacking note

Targets ci/container-publish (PR #35). Will retarget main automatically as the chain merges.

🤖 Generated with Claude Code

## Summary Five MCP tools — `cron_schedule` / `cron_list` / `cron_cancel` / `cron_edit` / `cron_trigger` — let an agent register, manage, and manually fire its own cron jobs. Jobs persist to a single global `cron.json` under `PathKind.Data`. The execution path is intentionally a stub today: when a job's `NextFireAt` elapses (or `cron_trigger` is called), the scheduler logs the would-have-been agent input and recomputes `NextFireAt`. The single site to upgrade when fires graduate from stub to real is `CronScheduler.FireSingleAsync`. Closes the *Cron tool* item under TASKS.md → "Agent orchestration & context". ## What's in here ### `src/LlamaShears.Core/Cron/` - `CronJob` (record) + `CronJobEdit` (record) — domain types. - `ICronStore` + `JsonCronStore` — single-file persistence. `SemaphoreSlim` serialises mutations; saves are atomic (write to `cron.json.tmp`, then `File.Move(..., overwrite: true)`). Corrupt JSON on load logs and starts empty rather than refusing to boot. - `ICronScheduler` + `CronScheduler` — Cronos expression parsing, agent scoping (every public mutation refuses cross-agent reads/writes), and the stub fire path. - `CronExecutor : BackgroundService` — wakes on `CronOptions.TickInterval` (default 30s) and asks the scheduler to fire any due jobs. - `CronOptions` — `FileName` (default `cron.json`), `TickInterval` (default 30s). - `CronServiceCollectionExtensions.AddCron()` — wires store + scheduler + executor; called from `AddCore`. ### `src/LlamaShears.Api/Tools/ModelContextProtocol/Cron/` Five `[McpServerToolType]` classes, one tool method each, mirroring the existing memory/filesystem tool layout: - `cron_schedule(name, cronExpression, prompt)` - `cron_list()` - `cron_cancel(id)` - `cron_edit(id, name?, cronExpression?, prompt?, enabled?)` - `cron_trigger(id)` — manual fire via the same `FireSingleAsync` path the executor uses All tools resolve the calling agent through `IAgentWorkspaceLocator` (same pattern as the memory tools). Refused: missing agent on the request, malformed GUID, unparseable cron expression. ### Storage Anchored on `IShearsPaths.GetPath(PathKind.Data, ensureExists: true)`. Single global file, by spec — there is one cron store regardless of how many agents are configured. Agent scoping is enforced at the scheduler boundary. ### Cron expression library [Cronos 0.10.0](https://www.nuget.org/packages/Cronos), MIT-licensed. Default 5-field form (minute, hour, day-of-month, month, day-of-week), evaluated in UTC. ## Tests 13 new TUnit cases under `tests/LlamaShears.UnitTests/Cron/`: - **`JsonCronStoreTests`** — fresh-empty, upsert round-trip across instances, upsert-replaces-by-id, remove idempotence, garbage JSON loads empty. - **`CronSchedulerTests`** — schedule computes next fire, schedule rejects unparseable expression, list is agent-scoped, cancel refuses other-agent jobs, edit patches only provided fields, edit recomputes next fire when expression changes, trigger updates last/next, fire-due skips disabled and not-yet-due jobs. `FakeTimeProvider` (Microsoft.Extensions.TimeProvider.Testing) drives the time-sensitive cases; `JsonCronStore` is exercised against a real tempdir per test for round-trip realism. ## Test plan - [x] `dotnet test --solution LlamaShears.slnx` — all 382 passing (was 369 before this PR). - [x] Husky `dotnet-test-on-source-change` pre-commit check passed. - [x] Husky `docs-api-up-to-date` pre-push check passed. - [x] No XML doc warnings (concrete types follow ADR-0012; only the two interfaces — `ICronStore`, `ICronScheduler` — carry doc comments). ## Stacking note Targets `ci/container-publish` (PR #35). Will retarget `main` automatically as the chain merges. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
CLAassistant commented 2026-05-07 11:24:06 -04:00 (Migrated from github.com)

CLA assistant check
All committers have signed the CLA.

[![CLA assistant check](https://cla-assistant.io/pull/badge/signed)](https://cla-assistant.io/jasoncouture/llama-shears?pullRequest=36) <br/>All committers have signed the CLA.
copilot-pull-request-reviewer[bot] (Migrated from github.com) reviewed 2026-05-07 11:29:31 -04:00
copilot-pull-request-reviewer[bot] (Migrated from github.com) left a comment

Pull request overview

Adds a new cron scheduling subsystem and MCP tool surface so agents can schedule, list, edit, cancel, and manually trigger cron jobs that persist to a single JSON store under PathKind.Data. Execution is intentionally stubbed: due jobs log the would-have-been agent prompt and advance NextFireAt.

Changes:

  • Introduces core cron domain, persistence (JsonCronStore), scheduling (CronScheduler), and a background executor (CronExecutor) wired via AddCron() and AddCore().
  • Adds five MCP tools (cron_schedule, cron_list, cron_cancel, cron_edit, cron_trigger) registered in the MCP tool collection.
  • Adds unit tests covering store persistence behavior and scheduler semantics (including agent scoping and time-driven behavior).

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/LlamaShears.UnitTests/Cron/JsonCronStoreTests.cs Adds unit coverage for JSON-backed cron persistence (round-trip, replace, remove, corrupt JSON).
tests/LlamaShears.UnitTests/Cron/CronSchedulerTests.cs Adds unit coverage for scheduling, agent scoping, editing, triggering, and firing-due logic using FakeTimeProvider.
src/LlamaShears.Core/LlamaShears.Core.csproj Adds Cronos package reference.
src/LlamaShears.Core/Cron/JsonCronStore.cs Implements single-file JSON persistence with in-memory cache + atomic save.
src/LlamaShears.Core/Cron/ICronStore.cs Defines persistence interface for cron jobs.
src/LlamaShears.Core/Cron/ICronScheduler.cs Defines agent-scoped cron operations and executor surface.
src/LlamaShears.Core/Cron/CronServiceCollectionExtensions.cs Adds AddCron() DI wiring and options validation.
src/LlamaShears.Core/Cron/CronScheduler.cs Implements scheduling, agent scoping, edit/cancel/trigger, and stub fire advancement.
src/LlamaShears.Core/Cron/CronOptions.cs Defines cron configuration options (file name, tick interval).
src/LlamaShears.Core/Cron/CronJobEdit.cs Defines patch model for job edits.
src/LlamaShears.Core/Cron/CronJob.cs Defines persisted cron job record shape.
src/LlamaShears.Core/Cron/CronExecutor.cs Adds background tick loop that calls FireDueAsync.
src/LlamaShears.Core/CoreServiceCollectionExtensions.cs Enables cron subsystem from AddCore().
src/LlamaShears.Api/Tools/ModelContextProtocol/ModelContextProtocolServiceCollectionExtensions.cs Registers the new cron MCP tools.
src/LlamaShears.Api/Tools/ModelContextProtocol/Cron/ScheduleCronTool.cs Implements cron_schedule MCP tool wrapper around the scheduler.
src/LlamaShears.Api/Tools/ModelContextProtocol/Cron/ListCronTool.cs Implements cron_list MCP tool wrapper around the scheduler.
src/LlamaShears.Api/Tools/ModelContextProtocol/Cron/CancelCronTool.cs Implements cron_cancel MCP tool wrapper around the scheduler.
src/LlamaShears.Api/Tools/ModelContextProtocol/Cron/EditCronTool.cs Implements cron_edit MCP tool wrapper around the scheduler.
src/LlamaShears.Api/Tools/ModelContextProtocol/Cron/TriggerCronTool.cs Implements cron_trigger MCP tool wrapper around the scheduler.

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

## Pull request overview Adds a new cron scheduling subsystem and MCP tool surface so agents can schedule, list, edit, cancel, and manually trigger cron jobs that persist to a single JSON store under `PathKind.Data`. Execution is intentionally stubbed: due jobs log the would-have-been agent prompt and advance `NextFireAt`. **Changes:** - Introduces core cron domain, persistence (`JsonCronStore`), scheduling (`CronScheduler`), and a background executor (`CronExecutor`) wired via `AddCron()` and `AddCore()`. - Adds five MCP tools (`cron_schedule`, `cron_list`, `cron_cancel`, `cron_edit`, `cron_trigger`) registered in the MCP tool collection. - Adds unit tests covering store persistence behavior and scheduler semantics (including agent scoping and time-driven behavior). ### Reviewed changes Copilot reviewed 19 out of 19 changed files in this pull request and generated 6 comments. <details> <summary>Show a summary per file</summary> | File | Description | | ---- | ----------- | | tests/LlamaShears.UnitTests/Cron/JsonCronStoreTests.cs | Adds unit coverage for JSON-backed cron persistence (round-trip, replace, remove, corrupt JSON). | | tests/LlamaShears.UnitTests/Cron/CronSchedulerTests.cs | Adds unit coverage for scheduling, agent scoping, editing, triggering, and firing-due logic using `FakeTimeProvider`. | | src/LlamaShears.Core/LlamaShears.Core.csproj | Adds Cronos package reference. | | src/LlamaShears.Core/Cron/JsonCronStore.cs | Implements single-file JSON persistence with in-memory cache + atomic save. | | src/LlamaShears.Core/Cron/ICronStore.cs | Defines persistence interface for cron jobs. | | src/LlamaShears.Core/Cron/ICronScheduler.cs | Defines agent-scoped cron operations and executor surface. | | src/LlamaShears.Core/Cron/CronServiceCollectionExtensions.cs | Adds `AddCron()` DI wiring and options validation. | | src/LlamaShears.Core/Cron/CronScheduler.cs | Implements scheduling, agent scoping, edit/cancel/trigger, and stub fire advancement. | | src/LlamaShears.Core/Cron/CronOptions.cs | Defines cron configuration options (file name, tick interval). | | src/LlamaShears.Core/Cron/CronJobEdit.cs | Defines patch model for job edits. | | src/LlamaShears.Core/Cron/CronJob.cs | Defines persisted cron job record shape. | | src/LlamaShears.Core/Cron/CronExecutor.cs | Adds background tick loop that calls `FireDueAsync`. | | src/LlamaShears.Core/CoreServiceCollectionExtensions.cs | Enables cron subsystem from `AddCore()`. | | src/LlamaShears.Api/Tools/ModelContextProtocol/ModelContextProtocolServiceCollectionExtensions.cs | Registers the new cron MCP tools. | | src/LlamaShears.Api/Tools/ModelContextProtocol/Cron/ScheduleCronTool.cs | Implements `cron_schedule` MCP tool wrapper around the scheduler. | | src/LlamaShears.Api/Tools/ModelContextProtocol/Cron/ListCronTool.cs | Implements `cron_list` MCP tool wrapper around the scheduler. | | src/LlamaShears.Api/Tools/ModelContextProtocol/Cron/CancelCronTool.cs | Implements `cron_cancel` MCP tool wrapper around the scheduler. | | src/LlamaShears.Api/Tools/ModelContextProtocol/Cron/EditCronTool.cs | Implements `cron_edit` MCP tool wrapper around the scheduler. | | src/LlamaShears.Api/Tools/ModelContextProtocol/Cron/TriggerCronTool.cs | Implements `cron_trigger` MCP tool wrapper around the scheduler. | </details> --- 💡 <a href="/jasoncouture/llama-shears/new/ci/container-publish?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 +1,238 @@
using Cronos;
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-07 11:29:30 -04:00

FireDueAsync doesn’t isolate failures per job. If FireSingleAsync throws for one persisted job (e.g., invalid CronExpression from manual edits), the method exits and remaining due jobs won’t fire on that tick. Consider catching/logging exceptions around the per-job FireSingleAsync call so other jobs still advance.

FireDueAsync doesn’t isolate failures per job. If FireSingleAsync throws for one persisted job (e.g., invalid CronExpression from manual edits), the method exits and remaining due jobs won’t fire on that tick. Consider catching/logging exceptions around the per-job FireSingleAsync call so other jobs still advance.
@ -0,0 +112,4 @@
var newPrompt = edit.Prompt ?? existing.Prompt;
var newEnabled = edit.Enabled ?? existing.Enabled;
var newExpression = edit.CronExpression ?? existing.CronExpression;
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-07 11:29:29 -04:00

EditAsync allows setting Name/Prompt to empty/whitespace (because it only null-coalesces). ScheduleAsync rejects blank values, so this creates an inconsistent API and can persist invalid job state. Consider validating that any provided edit.Name/edit.Prompt are non-empty (and rejecting whitespace-only updates).

EditAsync allows setting Name/Prompt to empty/whitespace (because it only null-coalesces). ScheduleAsync rejects blank values, so this creates an inconsistent API and can persist invalid job state. Consider validating that any provided edit.Name/edit.Prompt are non-empty (and rejecting whitespace-only updates).
@ -0,0 +192,4 @@
// intentionally not logged — it is user/agent-provided text that
// can carry secrets; only the length is recorded.
LogStubFire(_logger, job.Id, job.AgentId, manual, job.Prompt.Length);
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-07 11:29:29 -04:00

The stub fire path logs the full user-provided Prompt at Information level. Prompts can contain secrets or other sensitive content, so this can leak data into application logs. Consider truncating/redacting the prompt, logging only metadata (length/hash), or lowering the log level.

The stub fire path logs the full user-provided Prompt at Information level. Prompts can contain secrets or other sensitive content, so this can leak data into application logs. Consider truncating/redacting the prompt, logging only metadata (length/hash), or lowering the log level.
@ -0,0 +200,4 @@
LastFiredAt = firedAt,
NextFireAt = nextFireAt,
};
await _store.UpsertAsync(updated, cancellationToken).ConfigureAwait(false);
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-07 11:29:31 -04:00

FireSingleAsync persists an updated CronJob built from the instance passed in. If the job was concurrently edited after it was read (via GetAllAsync/GetAsync), this UpsertAsync can overwrite those edits (lost updates to name/prompt/enabled/expression). Consider reloading the latest job inside FireSingleAsync (or adding an atomic store update) before writing LastFiredAt/NextFireAt.

FireSingleAsync persists an updated CronJob built from the instance passed in. If the job was concurrently edited after it was read (via GetAllAsync/GetAsync), this UpsertAsync can overwrite those edits (lost updates to name/prompt/enabled/expression). Consider reloading the latest job inside FireSingleAsync (or adding an atomic store update) before writing LastFiredAt/NextFireAt.
@ -0,0 +1,159 @@
using System.Text.Json;
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-07 11:29:30 -04:00

loaded.ToDictionary(j => j.Id) will throw if the JSON file contains duplicate ids (e.g., from manual edits/merge conflicts), preventing the cron store from loading. Consider deduping (e.g., last-write-wins) or logging and skipping duplicates instead of throwing.

loaded.ToDictionary(j => j.Id) will throw if the JSON file contains duplicate ids (e.g., from manual edits/merge conflicts), preventing the cron store from loading. Consider deduping (e.g., last-write-wins) or logging and skipping duplicates instead of throwing.
@ -0,0 +112,4 @@
{
await using var stream = File.OpenRead(path);
var loaded = await JsonSerializer
.DeserializeAsync<List<CronJob>>(stream, _jsonOptions, cancellationToken)
copilot-pull-request-reviewer[bot] (Migrated from github.com) commented 2026-05-07 11:29:30 -04:00

JsonCronStore only catches JsonException during load. File.OpenRead / DeserializeAsync can also throw IO-related exceptions (IOException/UnauthorizedAccessException), which would currently bubble up and potentially fail startup. Consider catching those as well (logging and starting empty, similar to AgentConfigProvider).

JsonCronStore only catches JsonException during load. File.OpenRead / DeserializeAsync can also throw IO-related exceptions (IOException/UnauthorizedAccessException), which would currently bubble up and potentially fail startup. Consider catching those as well (logging and starting empty, similar to AgentConfigProvider).
github-actions[bot] commented 2026-05-07 14:13:45 -04:00 (Migrated from github.com)
Package Line Rate Branch Rate Complexity Health
LlamaShears.Core.Abstractions.Context 100% 100% 4
LlamaShears.Provider.Ollama 3% 1% 166
LlamaShears.IntegrationTests 87% 73% 71
LlamaShears.Core 46% 32% 861
LlamaShears.Core.Abstractions.Content 0% 100% 1
LlamaShears.Core.Abstractions.Caching 100% 100% 1
LlamaShears.Core.Eventing 96% 76% 51
StrangeSoft.Plugins.Host 20% 21% 87
LlamaShears.Core.Abstractions.Provider 32% 20% 66
LlamaShears.Core.Abstractions.Memory 0% 100% 3
LlamaShears.Api.Web 35% 20% 333
LlamaShears.Hosting 100% 100% 4
LlamaShears.Core.Abstractions.Events 21% 6% 79
LlamaShears.Core.Abstractions.SystemPrompt 100% 100% 2
LlamaShears 65% 25% 11
LlamaShears.Core.Abstractions.PromptContext 89% 100% 2
LlamaShears.Provider.Onnx.Embeddings 4% 0% 68
LlamaShears.Plugins.Host 34% 24% 36
LlamaShears.Core.Abstractions.Agent 73% 100% 11
LlamaShears.Api 10% 3% 342
LlamaShears.Plugins 0% 100% 1
LlamaShears.Core.Eventing.Extensions 100% 100% 1
LlamaShears.Core.Abstractions.Context 100% 100% 4
LlamaShears.Provider.Ollama 3% 1% 166
LlamaShears.Core 45% 31% 861
LlamaShears.Core.Abstractions.Content 0% 100% 1
LlamaShears.Core.Abstractions.Caching 100% 100% 1
LlamaShears.Core.Eventing 96% 76% 51
StrangeSoft.Plugins.Host 20% 21% 87
LlamaShears.Core.Abstractions.Provider 32% 20% 66
LlamaShears.Core.Abstractions.Memory 0% 100% 3
LlamaShears.Api.Web 22% 12% 333
LlamaShears.Hosting 100% 100% 4
LlamaShears.Core.Abstractions.Events 21% 6% 79
LlamaShears.Core.Abstractions.SystemPrompt 100% 100% 2
LlamaShears 65% 25% 11
LlamaShears.Core.Abstractions.PromptContext 89% 100% 2
LlamaShears.Provider.Onnx.Embeddings 4% 0% 68
LlamaShears.Plugins.Host 34% 24% 36
LlamaShears.Core.Abstractions.Agent 73% 100% 11
LlamaShears.Api 8% 1% 342
LlamaShears.Plugins 0% 100% 1
LlamaShears.Core.Eventing.Extensions 100% 100% 1
LlamaShears.Core.Abstractions.Context 100% 100% 4
LlamaShears.Provider.Ollama 44% 24% 166
LlamaShears.Core 47% 43% 861
LlamaShears.Core.Abstractions.Content 0% 100% 1
LlamaShears.Core.Abstractions.Caching 100% 100% 1
LlamaShears.Core.Eventing 93% 86% 51
LlamaShears.Core.Abstractions.Provider 78% 64% 66
LlamaShears.Core.Abstractions.Memory 100% 100% 3
LlamaShears.Hosting 100% 100% 4
LlamaShears.Core.Abstractions.Events 15% 3% 79
LlamaShears.Core.Abstractions.SystemPrompt 100% 100% 2
LlamaShears.Core.Abstractions.PromptContext 89% 100% 2
LlamaShears.Provider.Onnx.Embeddings 33% 36% 68
LlamaShears.Core.Abstractions.Agent 86% 100% 11
LlamaShears.Api 27% 29% 342
LlamaShears.Core.Eventing.Extensions 100% 100% 1
LlamaShears.Analyzers 89% 76% 199
LlamaShears.Analyzers.CodeFixes 85% 69% 60
Summary 50% (8154 / 20977) 39% (1585 / 5713) 6252
Package | Line Rate | Branch Rate | Complexity | Health -------- | --------- | ----------- | ---------- | ------ LlamaShears.Core.Abstractions.Context | 100% | 100% | 4 | ✔ LlamaShears.Provider.Ollama | 3% | 1% | 166 | ❌ LlamaShears.IntegrationTests | 87% | 73% | 71 | ✔ LlamaShears.Core | 46% | 32% | 861 | ❌ LlamaShears.Core.Abstractions.Content | 0% | 100% | 1 | ❌ LlamaShears.Core.Abstractions.Caching | 100% | 100% | 1 | ✔ LlamaShears.Core.Eventing | 96% | 76% | 51 | ✔ StrangeSoft.Plugins.Host | 20% | 21% | 87 | ❌ LlamaShears.Core.Abstractions.Provider | 32% | 20% | 66 | ❌ LlamaShears.Core.Abstractions.Memory | 0% | 100% | 3 | ❌ LlamaShears.Api.Web | 35% | 20% | 333 | ❌ LlamaShears.Hosting | 100% | 100% | 4 | ✔ LlamaShears.Core.Abstractions.Events | 21% | 6% | 79 | ❌ LlamaShears.Core.Abstractions.SystemPrompt | 100% | 100% | 2 | ✔ LlamaShears | 65% | 25% | 11 | ➖ LlamaShears.Core.Abstractions.PromptContext | 89% | 100% | 2 | ✔ LlamaShears.Provider.Onnx.Embeddings | 4% | 0% | 68 | ❌ LlamaShears.Plugins.Host | 34% | 24% | 36 | ❌ LlamaShears.Core.Abstractions.Agent | 73% | 100% | 11 | ➖ LlamaShears.Api | 10% | 3% | 342 | ❌ LlamaShears.Plugins | 0% | 100% | 1 | ❌ LlamaShears.Core.Eventing.Extensions | 100% | 100% | 1 | ✔ LlamaShears.Core.Abstractions.Context | 100% | 100% | 4 | ✔ LlamaShears.Provider.Ollama | 3% | 1% | 166 | ❌ LlamaShears.Core | 45% | 31% | 861 | ❌ LlamaShears.Core.Abstractions.Content | 0% | 100% | 1 | ❌ LlamaShears.Core.Abstractions.Caching | 100% | 100% | 1 | ✔ LlamaShears.Core.Eventing | 96% | 76% | 51 | ✔ StrangeSoft.Plugins.Host | 20% | 21% | 87 | ❌ LlamaShears.Core.Abstractions.Provider | 32% | 20% | 66 | ❌ LlamaShears.Core.Abstractions.Memory | 0% | 100% | 3 | ❌ LlamaShears.Api.Web | 22% | 12% | 333 | ❌ LlamaShears.Hosting | 100% | 100% | 4 | ✔ LlamaShears.Core.Abstractions.Events | 21% | 6% | 79 | ❌ LlamaShears.Core.Abstractions.SystemPrompt | 100% | 100% | 2 | ✔ LlamaShears | 65% | 25% | 11 | ➖ LlamaShears.Core.Abstractions.PromptContext | 89% | 100% | 2 | ✔ LlamaShears.Provider.Onnx.Embeddings | 4% | 0% | 68 | ❌ LlamaShears.Plugins.Host | 34% | 24% | 36 | ❌ LlamaShears.Core.Abstractions.Agent | 73% | 100% | 11 | ➖ LlamaShears.Api | 8% | 1% | 342 | ❌ LlamaShears.Plugins | 0% | 100% | 1 | ❌ LlamaShears.Core.Eventing.Extensions | 100% | 100% | 1 | ✔ LlamaShears.Core.Abstractions.Context | 100% | 100% | 4 | ✔ LlamaShears.Provider.Ollama | 44% | 24% | 166 | ❌ LlamaShears.Core | 47% | 43% | 861 | ❌ LlamaShears.Core.Abstractions.Content | 0% | 100% | 1 | ❌ LlamaShears.Core.Abstractions.Caching | 100% | 100% | 1 | ✔ LlamaShears.Core.Eventing | 93% | 86% | 51 | ✔ LlamaShears.Core.Abstractions.Provider | 78% | 64% | 66 | ✔ LlamaShears.Core.Abstractions.Memory | 100% | 100% | 3 | ✔ LlamaShears.Hosting | 100% | 100% | 4 | ✔ LlamaShears.Core.Abstractions.Events | 15% | 3% | 79 | ❌ LlamaShears.Core.Abstractions.SystemPrompt | 100% | 100% | 2 | ✔ LlamaShears.Core.Abstractions.PromptContext | 89% | 100% | 2 | ✔ LlamaShears.Provider.Onnx.Embeddings | 33% | 36% | 68 | ❌ LlamaShears.Core.Abstractions.Agent | 86% | 100% | 11 | ✔ LlamaShears.Api | 27% | 29% | 342 | ❌ LlamaShears.Core.Eventing.Extensions | 100% | 100% | 1 | ✔ LlamaShears.Analyzers | 89% | 76% | 199 | ✔ LlamaShears.Analyzers.CodeFixes | 85% | 69% | 60 | ✔ **Summary** | **50%** (8154 / 20977) | **39%** (1585 / 5713) | **6252** | ❌ <!-- Sticky Pull Request Commentcoverage -->
Sign in to join this conversation.
No description provided.