Upgrade DotPrompt.Sql to full feature parity with DotPrompt 0.0.6.1#7
Conversation
- Bump DotPrompt package reference from 0.0.5.1 to 0.0.6.1 - Add Version, Temperature, FewShots, OutputSchema fields to SqlPromptEntity - Fix MaxTokens to be nullable (int?) matching PromptConfig - Rewrite ToPromptFile() to map all new fields (Version, Temperature, FewShots, Output.Schema) - Replace manual YAML parsing in FromPromptFile(string) with PromptFile.FromFile() - Add FromPromptFile(PromptFile) overload for direct mapping - Fix SqlTablePromptStore.Save() bug: was using constructor file path instead of promptFile param - Remove unused _promptFile field; simplify SqlTablePromptStore constructor to take only IPromptRepository - Add OutputSchema, Temperature, FewShots columns to PromptFile table (with migration guards) - Make MaxTokens column nullable in schema - Update sp_AddSqlPrompt stored procedure with new params and NULL-safe change detection - Update LoadPrompts.sql and GetLatestPromptByName.sql to SELECT new columns - Update InsertPromptFile.sql with new columns - Update SqlPromptRepository to pass new params to stored procedure - Update tests to use valid parameter names (not reserved words like Temperature/TopP) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace outdated feature list with full support table - Remove note about few-shot not being supported (now implemented) - Add installation snippet, code usage example, database schema section - Document new columns (Temperature, OutputSchema, FewShots) and migration behaviour - Fix broken image path Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fixes NU1605 downgrade error: DotPrompt.Sql.Cli had its own direct reference to DotPrompt 0.0.5.1 which conflicted with the 0.0.6.1 reference in DotPrompt.Sql. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR updates DotPrompt.Sql to align with newer DotPrompt prompt-file capabilities (v0.0.6.1), extending SQL persistence to cover additional prompt config fields and improving prompt-file parsing/serialization.
Changes:
- Bumped DotPrompt dependency to
0.0.6.1and expandedSqlPromptEntityto include Version/Temperature/OutputSchema/FewShots (+ nullable MaxTokens). - Updated SQL schema + queries + stored procedure to store/load the new fields and perform NULL-safe change detection.
- Reworked prompt-file mapping to delegate parsing to
PromptFile.FromFile()and fixedSqlTablePromptStore.Save()to use the providedPromptFile.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| readme.md | Rewritten docs: installation, CLI usage, supported-features table, and schema notes. |
| DotPrompt.Sql/SqlPromptStore.cs | Removes ctor prompt-file path; Save() now maps directly from PromptFile. |
| DotPrompt.Sql/SqlPromptRepository.cs | Passes new parameters (OutputSchema/Temperature/FewShots) into sp_AddSqlPrompt. |
| DotPrompt.Sql/SqlPromptEntity.cs | Adds new fields + rewrites To/From PromptFile mapping (JSON serialization for schema/few-shots). |
| DotPrompt.Sql/Resources/SqlQueries/LoadPrompts.sql | Loads latest prompt versions and now selects new columns. |
| DotPrompt.Sql/Resources/SqlQueries/InsertPromptFile.sql | Inserts new columns into PromptFile. |
| DotPrompt.Sql/Resources/SqlQueries/GetLatestPromptByName.sql | Retrieves latest prompt by name including new columns. |
| DotPrompt.Sql/Resources/SqlQueries/CreateDefaultPromptTables.sql | Adds/migrates columns (OutputSchema/Temperature/FewShots) + makes MaxTokens nullable. |
| DotPrompt.Sql/Resources/SqlQueries/AddSqlPrompt.sql | Updates stored proc signature, change detection, and insert for new columns. |
| DotPrompt.Sql/DotPrompt.Sql.csproj | Updates DotPrompt package reference. |
| DotPrompt.Sql.Test/TestSqlPromptEntity.cs | Updates tests to reflect new entity fields (adds Temperature in some cases). |
Comments suppressed due to low confidence (2)
DotPrompt.Sql.Test/TestSqlPromptEntity.cs:103
- New versioning fields/logic were added (
Temperature,OutputSchema,FewShots, nullableMaxTokens), but the tests don’t currently assert that changes to these new fields trigger a new version (or that they round-trip on retrieval). Adding coverage for at least one of these fields would help prevent regressions in the stored procedure change-detection logic.
[Fact]
public async Task AddSqlPrompt_ValidPrompt_InsertsSuccessfully()
{
// Arrange
var entity = new SqlPromptEntity
{
PromptName = "myprompt",
Model = "gpt4",
OutputFormat = "json",
MaxTokens = 500,
Temperature = 0.7f,
SystemPrompt = "Optimize SQL queries.",
UserPrompt = "Suggest indexing improvements.",
Parameters = new Dictionary<string, string>
{
{ "query", "string" },
{ "topP", "number" }
},
Default = new Dictionary<string, object>
{
{ "topP", "0.9" }
}
};
// Act
bool result = await _repository.AddSqlPrompt(entity);
// Assert
Assert.True(result, "Expected new prompt version to be inserted.");
}
DotPrompt.Sql/Resources/SqlQueries/AddSqlPrompt.sql:57
- Change detection for parameters only checks for params present in
@Parametersthat are missing/changed inPromptParameters. If a parameter is removed (exists inPromptParametersbut not in@Parameters), this won’t detect it and no new version will be inserted, even though prompt content changed. Add the inverse check (rows inPromptParametersfor the existing version that don’t exist in@Parameters).
OR EXISTS (
-- Parameters changed?
SELECT 1 FROM @Parameters p
WHERE NOT EXISTS (
SELECT 1 FROM PromptParameters pp
WHERE pp.PromptId = @ExistingPromptId
AND pp.VersionNumber = @ExistingVersion
AND pp.ParameterName = p.ParameterName
AND pp.ParameterValue = p.ParameterValue
)
)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| UserPrompt, | ||
| FewShots, | ||
| VersionNumber, | ||
| ROW_NUMBER() OVER (PARTITION BY PromptName ORDER BY VersionNumber DESC) AS RowNum |
There was a problem hiding this comment.
VersionNumber is selected but not aliased to Version, so Dapper won’t populate SqlPromptEntity.Version (it will stay at the default 1). Since ToPromptFile() uses Version, loaded prompt files will report the wrong version. Consider aliasing VersionNumber AS Version in both the CTE and final SELECT (or renaming the C# property to VersionNumber).
| SELECT | ||
| lp.PromptId, | ||
| lp.PromptName, | ||
| lp.VersionNumber, | ||
| lp.CreatedAt, | ||
| lp.ModifiedAt, |
There was a problem hiding this comment.
VersionNumber is returned without an alias, so Dapper won’t map it onto SqlPromptEntity.Version and callers will see PromptFile.Version as 1 even when the DB has higher versions. Alias lp.VersionNumber AS Version (or rename the C# property to VersionNumber) to keep versions consistent.
| return new SqlPromptEntity | ||
| { | ||
| throw new ApplicationException($"Mandatory key not present", knfe); | ||
| } | ||
|
|
||
| return sqlPromptEntity; | ||
| PromptName = promptFile.Name, | ||
| Version = promptFile.Version, | ||
| Model = promptFile.Model, | ||
| OutputFormat = promptFile.Config.OutputFormat.ToString(), | ||
| OutputSchema = outputSchema, | ||
| MaxTokens = promptFile.Config.MaxTokens, | ||
| Temperature = promptFile.Config.Temperature, | ||
| Parameters = promptFile.Config.Input.Parameters, | ||
| Default = promptFile.Config.Input.Default, | ||
| SystemPrompt = promptFile.Prompts?.System ?? string.Empty, | ||
| UserPrompt = promptFile.Prompts?.User ?? string.Empty, | ||
| FewShots = fewShots | ||
| }; |
There was a problem hiding this comment.
FromPromptFile(PromptFile) copies promptFile.Version into SqlPromptEntity.Version, but SqlPromptRepository.AddSqlPrompt / sp_AddSqlPrompt never use this value (the proc always auto-increments VersionNumber). This makes the mapping misleading and breaks round-tripping if a prompt file carries an explicit version. Either persist the provided version (add a proc parameter and insert it) or stop mapping promptFile.Version here and treat DB versioning as the source of truth.
| - **`ParameterDefaults`** — default values linked to parameters | ||
|
|
||
| It doesn't currently support the **Few Shot Prompt** section but will shortly. It has been tested only for only username and password database access but will be tested with the others so whilst config is supported access may well break. Let me know if this is the case. | ||
| New columns added in v0.2.3: |
There was a problem hiding this comment.
The README says “New columns added in v0.2.3”, but the package version in DotPrompt.Sql.csproj is still 0.2.2. Please align the documented version with the actual package version (or bump the package version if 0.2.3 is intended).
| New columns added in v0.2.3: | |
| New columns added in v0.2.2: |
| @@ -64,8 +70,8 @@ SET @NewVersion = ISNULL(@ExistingVersion, 0) + 1; | |||
| ) | |||
There was a problem hiding this comment.
Similarly, default-value change detection only checks for defaults present in @Defaults that are missing/changed in the DB. If a default is removed (exists in ParameterDefaults for the existing version but not in @Defaults), this won’t trigger a new version. Consider adding an inverse EXISTS check for DB defaults not present in @Defaults.
| ) | |
| ) | |
| OR EXISTS ( | |
| -- Defaults removed? | |
| SELECT 1 | |
| FROM ParameterDefaults pd | |
| JOIN PromptParameters pp ON pd.ParameterId = pp.ParameterId | |
| WHERE pp.PromptId = @ExistingPromptId | |
| AND pp.VersionNumber = @ExistingVersion | |
| AND pd.VersionNumber = @ExistingVersion | |
| AND NOT EXISTS ( | |
| SELECT 1 | |
| FROM @Defaults d | |
| WHERE d.ParameterName = pp.ParameterName | |
| AND d.DefaultValue = pd.DefaultValue | |
| ) | |
| ) |
Why
DotPrompt.Sql was pinned to DotPrompt
0.0.5.1and was missing several features that had since been added to the core library: few-shot examples, structured output schemas, temperature configuration, and prompt versioning. There was also a bug inSqlTablePromptStore.Save()that caused it to silently ignore the prompt file passed to it, and the manual YAML parsing inFromPromptFile(string)duplicated fragile logic already handled by DotPrompt itself.What changed
Bug fix
SqlTablePromptStore.Save()was using_promptFile(a path passed to the constructor) instead of thepromptFileparameter — meaning every save silently wrote the wrong prompt. Fixed to use the parameter. The now-redundantstring promptFileconstructor argument and_promptFilefield have been removed.New fields —
SqlPromptEntityAdded
Version,Temperature(float?),OutputSchema(JSON string), andFewShots(JSON array string) to mirror all fields onPromptFileandPromptConfig.MaxTokenscorrected frominttoint?to match the nullable property inPromptConfig.ToPromptFile()/FromPromptFile()rewriteToPromptFile()now maps all new fields and no longer returnsnullwhen parameters or defaults are empty — it always returns a validPromptFile.FromPromptFile(string)no longer manually re-implements YAML deserialization. It delegates toPromptFile.FromFile()(picking up all DotPrompt validation for free) then maps through the newFromPromptFile(PromptFile)overload.FromPromptFile(PromptFile)overload enables direct mapping from a parsed object, useful inSqlTablePromptStore.Save().Database schema
PromptFiletable: addedTemperature FLOAT NULL,OutputSchema NVARCHAR(MAX) NULL,FewShots NVARCHAR(MAX) NULL;MaxTokenschanged to nullable.IF NOT EXISTSguards so existing databases are migrated non-destructively.sp_AddSqlPromptstored procedure updated with new parameters and NULL-safe change-detection logic for the new columns.LoadPrompts.sqlandGetLatestPromptByName.sqlupdated to SELECT the new columns.Package & docs
0.0.5.1→0.0.6.1.readme.mdrewritten to reflect full feature parity, with an accurate feature table, installation snippet, code usage example, and schema documentation. The "few-shot not yet supported" note has been removed.Migration notes
Existing SQL Server databases will be migrated automatically on next startup — no manual DDL required. The stored procedure is replaced with
CREATE OR ALTER, which is idempotent.Areas worth a close look
sp_AddSqlPromptfor the new nullable columns (Temperature,OutputSchema,FewShots) uses the pattern(col = @val OR (col IS NULL AND @val IS NULL))— please verify this covers all edge cases for your environment.FewShotsandOutputSchemaare stored as raw JSON strings inNVARCHAR(MAX). If query-time JSON introspection is ever needed, a computed column or JSON index could be added later.