Skip to content

Python semantic layer: injection resolution and the public API - #256

Draft
jat255 wants to merge 3 commits into
jat255/wwmt-layer-collectionfrom
jat255/wwmt-injections
Draft

Python semantic layer: injection resolution and the public API#256
jat255 wants to merge 3 commits into
jat255/wwmt-layer-collectionfrom
jat255/wwmt-injections

Conversation

@jat255

@jat255 jat255 commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Last of four stacked PRs building the Python semantic layer (M3). Based on #249. Completes the milestone.

The one-sentence version: some measure arguments are not the model's to fill in — a database connection, say — so this PR adds the small function that matches each of those Injected arguments to a named data source, and it opens the public API: measure, semantic_layer, and their types are now importable from commons itself.

Carrying on the recipe-box analogy from #249: an Injected argument is an ingredient the kitchen supplies, not the chef. resolve_injections() is the stocking step that matches each kitchen-supplied ingredient to a named pantry, by name.

The three rules. For each injected argument of each measure: an argument named after a data source receives that source's connection, even when the argument has a default. One matching no source keeps its default. One matching no source and having no default is an error naming the measure, the arguments, and the sources that are available. The error is raised here, at construction, so a measure that can never run is caught before the agent starts a conversation, not in the middle of one.

A deliberate boundary. resolve_injections(measures, injectables) takes a plain Mapping[str, Any], not a data-source type, and nothing in this milestone imports the data layer. That mirrors the R package's division of labor: resolve_injections() in pkg-r/R/measures.R also takes a plain named list, while measure_injectables(), the part that knows what a data source is, lives in pkg-r/R/commons.R with the agent. Nothing calls resolve_injections() yet for that reason — its caller is the agent constructor, which M5 adds, and which is where the error surfaces to a user.

The public API. __all__ gains Injected, Measure, SemanticLayer, measure, and semantic_layer. measure_schema_text() and resolve_injections() stay private, matching the R package's export discipline: they are seams the agent layer imports, not API a measure author uses. The test fixture files move to the public import path (from commons import Injected, measure) in the same commit, which is what checks the surface is usable the way a measure author will use it.

Verified on both supported interpreters: 187 tests pass on 3.11 and 3.13.

@jat255 jat255 changed the title jat255/wwmt injections Python semantic layer: injection resolution and the public API Sep 2, 2026
@jat255 jat255 added this to the py-M3: semantic layer milestone Sep 2, 2026
@jat255 jat255 added the py Affects the Python implementation label Sep 2, 2026
@jat255
jat255 force-pushed the jat255/wwmt-injections branch from 9c65851 to 9c2fc1d Compare September 3, 2026 00:31
@jat255
jat255 force-pushed the jat255/wwmt-injections branch from 9c2fc1d to 4e215d3 Compare September 4, 2026 04:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

py Affects the Python implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant