Run report generation without workspace state

This commit is contained in:
2026-08-01 19:52:22 +00:00
parent 4bdba6f2b7
commit 7ffc3dc603
21 changed files with 343 additions and 3464 deletions

View File

@@ -16,8 +16,8 @@ import (
)
const (
promptPreparationDebugSchemaVersion = "weatherreporter.prompt_preparation_debug.v1"
promptExecutionDebugSchemaVersion = "weatherreporter.prompt_execution_debug.v1"
promptPreparationDebugSchemaVersion = "weatherreporter.prompt_preparation_debug.v2"
promptExecutionDebugSchemaVersion = "weatherreporter.prompt_execution_debug.v2"
debugDirectoryMode = 0o700
debugFileMode = 0o600
)
@@ -64,7 +64,6 @@ type PromptDebugPreparation struct {
StartedAt time.Time `json:"startedAt"`
EndedAt time.Time `json:"endedAt"`
Duration time.Duration `json:"duration"`
DataPackagePath string `json:"dataPackagePath"`
}
// PromptPreparationDebugArtifact is the on-disk preparation debug record.
@@ -114,7 +113,6 @@ type PromptDebugExecution struct {
StartedAt time.Time `json:"startedAt"`
EndedAt time.Time `json:"endedAt"`
Duration time.Duration `json:"duration"`
DataPackagePath string `json:"dataPackagePath"`
}
// PromptExecutionDebugArtifact is the on-disk execution debug record.
@@ -340,7 +338,7 @@ func promptDebugPreparation(value promptexec.Preparation) PromptDebugPreparation
RenderedPromptHash: value.RenderedPromptHash, InputHashes: copyPromptDebugMap(value.InputHashes),
ProfileID: value.ProfileID, BackendID: value.BackendID, ModelName: value.ModelName,
Output: PromptDebugOutput{Format: value.Output.Format, ValidationMode: value.Output.ValidationMode, SchemaPath: value.Output.SchemaPath},
StartedAt: value.StartedAt, EndedAt: value.EndedAt, Duration: value.Duration, DataPackagePath: value.DataPackagePath,
StartedAt: value.StartedAt, EndedAt: value.EndedAt, Duration: value.Duration,
}
}
@@ -351,7 +349,7 @@ func promptDebugExecution(value promptexec.Execution) PromptDebugExecution {
InputHashes: copyPromptDebugMap(value.InputHashes), ProfileID: value.ProfileID,
BackendID: value.BackendID, ModelName: value.ModelName, GeneratedHash: value.GeneratedHash,
Usage: PromptDebugUsage{PromptTokens: value.Usage.PromptTokens, CompletionTokens: value.Usage.CompletionTokens, TotalTokens: value.Usage.TotalTokens, CachedTokens: value.Usage.CachedTokens, CacheWriteTokens: value.Usage.CacheWriteTokens},
StartedAt: value.StartedAt, EndedAt: value.EndedAt, Duration: value.Duration, DataPackagePath: value.DataPackagePath,
StartedAt: value.StartedAt, EndedAt: value.EndedAt, Duration: value.Duration,
}
}

View File

@@ -40,19 +40,19 @@ func TestPromptDebugWriterWritesIsolatedArtifacts(t *testing.T) {
t.Fatalf("WriteExecution() directory = %q, want %q", executionDir, preparationDir)
}
preparationData := readPromptDebugFile(t, filepath.Join(preparationDir, "preparation.json"))
for _, want := range []string{"Use the supplied weather facts.", `"type": "object"`, "https://llm.example.test/v1/chat?api_key=%5Bredacted%5D", `"temperature": 0.2`, `"api_key": "[redacted]"`} {
for _, want := range []string{"weatherreporter.prompt_preparation_debug.v2", "Use the supplied weather facts.", `"type": "object"`, "https://llm.example.test/v1/chat?api_key=%5Bredacted%5D", `"temperature": 0.2`, `"api_key": "[redacted]"`} {
if !strings.Contains(string(preparationData), want) {
t.Fatalf("preparation debug artifact missing %q:\n%s", want, preparationData)
}
}
executionData := readPromptDebugFile(t, filepath.Join(executionDir, "execution.json"))
for _, want := range []string{"Generated forecast prose.", "validation details", `"status": "passed"`} {
for _, want := range []string{"weatherreporter.prompt_execution_debug.v2", "Generated forecast prose.", "validation details", `"status": "passed"`} {
if !strings.Contains(string(executionData), want) {
t.Fatalf("execution debug artifact missing %q:\n%s", want, executionData)
}
}
for _, data := range [][]byte{preparationData, executionData} {
if strings.Contains(string(data), "credential") || strings.Contains(string(data), "resolved-secret-value") {
if strings.Contains(string(data), "credential") || strings.Contains(string(data), "resolved-secret-value") || strings.Contains(string(data), "dataPackagePath") {
t.Fatalf("debug artifact contains credentials:\n%s", data)
}
}
@@ -169,7 +169,7 @@ func promptDebugPreparationFixture() promptexec.Preparation {
PromptID: "weather.daily", PromptVersion: "v1", PromptHash: "prompt-hash", RenderedPromptHash: "rendered-hash",
InputHashes: map[string]string{"data_package": "input-hash"}, ProfileID: "local", BackendID: "local", ModelName: "weather-model",
Output: promptexec.OutputContract{Format: "json_schema", ValidationMode: "strict", SchemaPath: "schemas/daily.json"},
StartedAt: startedAt, EndedAt: startedAt.Add(time.Second), Duration: time.Second, DataPackagePath: "/packages/daily.yaml",
StartedAt: startedAt, EndedAt: startedAt.Add(time.Second), Duration: time.Second,
}
}
@@ -180,9 +180,9 @@ func promptDebugExecutionFixture() promptexec.Execution {
InputHashes: map[string]string{"data_package": "input-hash"}, ProfileID: "local", BackendID: "local", ModelName: "weather-model",
GeneratedHash: "generated-hash", Usage: promptexec.TokenUsage{PromptTokens: 10, CompletionTokens: 5, TotalTokens: 15},
StartedAt: startedAt, EndedAt: startedAt.Add(time.Second), Duration: time.Second,
Validation: promptexec.NewValidation(promptexec.ValidationPassed, "strict", "schemas/daily.json", []string{"validation details"}),
DataPackagePath: "/packages/daily.yaml", RawOutput: []byte("Generated forecast prose."),
Debug: &promptexec.ExecutionDebug{ValidationDiagnostics: []string{"validation details"}},
Validation: promptexec.NewValidation(promptexec.ValidationPassed, "strict", "schemas/daily.json", []string{"validation details"}),
RawOutput: []byte("Generated forecast prose."),
Debug: &promptexec.ExecutionDebug{ValidationDiagnostics: []string{"validation details"}},
}
}