Skip to content

Release v2.14.0

Choose a tag to compare

@github-actions github-actions released this 15 Sep 09:29
d4164e8

Add @cratis/ai: wire Cratis.Arc.ProxyGenerator.Build and publish the generated proxy package

Phase 3b of the Cratis.AI consolidation (plan Section 6) - the generated Arc command/query proxy
package both Direct and Studio will consume the package's read models and commands through.

Cratis.AI.csproj:

  • References Cratis.Arc.ProxyGenerator.Build directly (PrivateAssets=all), matching Studio's own
    Core.csproj rather than pulling it in transitively through the ASP.NET-oriented "Cratis"
    metapackage - the generator itself reflects over the compiled assembly with no ASP.NET Core
    hosting involved, so nothing more than Cratis.Arc.Core (already referenced) plus this build-time
    tool is needed.
  • CopyLocalLockFileAssemblies=true - required and non-obvious: the generator resolves Cratis.AI.dll's
    dependency closure (Cratis.Chronicle, Cratis.Fundamentals, ...) through a reflection-only
    MetadataLoadContext, which needs every referenced assembly physically present next to Cratis.AI.dll
    in the output directory. A plain class library does not copy its NuGet dependencies locally by
    default (an ASP.NET Core app, which is what Direct's and Studio's own proxy-generating projects
    are, does) - without this the generator crashed trying to resolve EventSourceId's base type
    from a Cratis.Chronicle it could not find.
  • CratisProxiesOutputPath points at Source/Cratis.AI.Proxies/generated, a subfolder rather than the
    package root: CratisProxiesSkipOutputDeletion=false (deliberate per plan Section 6.3, so a deleted
    command cannot leave a stale proxy) wipes its entire output directory on every build, which would
    otherwise take the package's own package.json/tsconfig.json/rollup.config.mjs/index.ts with it.
  • --namespace-root=Cratis.AI=. strips the redundant AI/ folder a literal namespace mapping would
    otherwise produce inside a package already named @cratis/ai.
  • Route prefix: /api/a-i/... via SegmentsToSkip=1, per the plan's own Section 6.4 recommendation -
    distinct and collision-proof against either product's own routes. Decision 0004 records the full
    reasoning for all of the above, including the alternatives rejected.

RecordAgentSessionUsage's command validator was removed entirely as a direct consequence of getting
this far: Arc's IModelGraphValidator already applies each ConceptAs property's own ConceptValidator
automatically (InputTokensValidator, CpuSecondsValidator, ...), so the command-level rules
duplicating "cannot be negative" were pure redundancy - and, as it turned out, the one thing standing
between this and a working build: the ProxyGenerator translates a validator's property-chain
expression literally, and CostUsd!.Value became a nonsensical c.costUsd.Value access on a
TypeScript property already flattened to a plain number. Validate at the concept, not the command,
for this class of property.

Source/Cratis.AI.Proxies (@cratis/ai): package.json/tsconfig.json/rollup.config.mjs modelled on
Arc's own @cratis/arc package, peer-depending on @cratis/arc, @cratis/arc.react, @cratis/fundamentals
and react per plan Section 6.2. A hand-maintained index.ts barrels the generated tree - the generator
emits one index.ts per generated folder but has no way to know which output path is a package root,
so it does not emit one at the top.

publish.yml:

  • verify job now runs a real dotnet build before the generated-proxies drift check, so the check
    actually compares a freshly regenerated tree against what is committed rather than the checked-out
    tree against itself (a gap the drift gate had from when it was first added with a "does not exist
    yet" no-op).
  • New publish-npm-packages job: rebuilds Cratis.AI, sets @cratis/ai's version to the same release
    version cratis/release-action determined, builds the rollup bundle, publishes with npm provenance -
    the same OIDC trusted-publishing shape publish-pi already uses.
  • verify-published now fails the run if Cratis.AI (NuGet) and @cratis/ai (npm) do not publish
    together - the two are one artifact split across two registries (plan Section 6.5), and letting one
    succeed while the other fails is exactly the version-skew risk #13 exists to prevent.

Also fixes two latent gaps from Phase 1 that only surfaced once a real bundled TypeScript package
existed to exercise them: eslint.config.mjs referenced eslint-plugin-react, which was never added to
package.json; vitest.config.ts's projects glob pointed at Source/JavaScript/* (Arc's own layout, not
this repository's Source/**/*).

Verified: yarn workspace @cratis/ai run ci (clean, lint, build) passes; dotnet build regenerates
Usage/RecordAgentSessionUsage + Usage/Trends/AgentUsageByWeek+AgentUsageByMonth +
Usage/Daily/AgentUsageByDay (1 command, 3 queries) with a clean TypeScript compile; all 109 remaining
.NET specs pass (110 minus the one spec for the now-removed command validator); the existing
Harness.Setup/Pi.Plugin/Verification workspace checks are unaffected.