Skip to content

feature: .NET source generator for .prompty files (codegen + tracing) #331

@sethjuarez

Description

@sethjuarez

Summary

Build a C# source generator that compiles .prompty files into typed C# classes at build time. This replaces the need for runtime YAML parsing and file loading entirely.

Motivation

Currently, using a .prompty file in C# requires:

var agent = PromptyLoader.Load("path/to/chat.prompty");
var result = await Pipeline.InvokeAgentAsync(agent, inputs: new Dictionary<string, object?> {
    ["firstName"] = "Jane",
    ["question"] = "What is the meaning of life?",
});

With a source generator, the same .prompty file would produce a typed class at build time:

// Auto-generated from chat.prompty
var result = await ChatPrompty.RunAsync(firstName: "Jane", question: "What is the meaning of life?");

This gives you IntelliSense, compile-time validation, and no runtime YAML parsing — the same pattern as Razor pages, gRPC stubs, and protobuf.

Scope

Phase 1: Basic source generator

  • Read .prompty files from the project (MSBuild AdditionalFiles or a custom <Prompty> item group)
  • Parse frontmatter at build time
  • Emit a typed class per .prompty file with:
    • Strongly-typed input parameters from inputSchema.properties
    • Typed return value from outputSchema (or string default)
    • Static RunAsync() / PrepareAsync() methods that delegate to the runtime pipeline
    • The raw prompty content embedded as a string constant (no file I/O at runtime)

Phase 2: Tracing attributes

  • Auto-generate OpenTelemetry Activity spans from prompty metadata (name, description, model info)
  • Emit [ActivitySource] registration and span creation in the generated code
  • Map prompty execution stages (render → parse → execute → process) to child spans
  • Include prompty metadata as span attributes (model ID, provider, template kind)

Phase 3: Validation and diagnostics

  • Emit compiler warnings/errors for:
    • Invalid YAML frontmatter
    • Missing required inputSchema properties without defaults
    • Unknown model.provider values
    • ${env:VAR} references (informational: "resolved at runtime")
  • Roslyn analyzer companion for IDE squiggles

Design Questions

  • Should the generated class name come from the name field or the filename?
  • Should we generate interfaces for testability (e.g., IChatPrompty)?
  • How should ${env:VAR} and ${file:path} references work in codegen context? (They're inherently runtime — the generator can embed them as deferred resolution)
  • NuGet packaging: Prompty.SourceGenerator as a separate analyzer package?

Supersedes

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions