-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
5 changed files
with
272 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package report | ||
|
||
import ( | ||
"io" | ||
"os" | ||
"path/filepath" | ||
"text/template" | ||
"time" | ||
|
||
pkgerrors "github.com/pkg/errors" | ||
"github.com/zimmski/osutil/bytesutil" | ||
|
||
"github.com/symflower/eval-dev-quality/evaluate/metrics" | ||
) | ||
|
||
// Markdown holds the values for exporting a Markdown report. | ||
type Markdown struct { | ||
// DateTime holds the timestamp of the evaluation. | ||
DateTime time.Time | ||
// Version holds the version of the evaluation tool. | ||
Version string | ||
|
||
// CSVPath holds the path of detailed CSV results. | ||
CSVPath string | ||
// LogPath holds the path of detailed logs. | ||
LogPath string | ||
|
||
// AssessmentPerModel holds | ||
AssessmentPerModel map[string]metrics.Assessments | ||
// TotalScore holds the total reachable score per task. | ||
// REMARK Used for category computation. | ||
TotalScore uint | ||
} | ||
|
||
// markdownTemplateContext holds the template for a Markdown report. | ||
type markdownTemplateContext struct { | ||
Markdown | ||
|
||
Categories []*metrics.AssessmentCategory | ||
ModelsPerCategory map[*metrics.AssessmentCategory][]string | ||
} | ||
|
||
// markdownTemplate holds the template for a Markdown report. | ||
var markdownTemplate = template.Must(template.New("template-report").Parse(bytesutil.StringTrimIndentations(` | ||
# Evaluation from {{.DateTime.Format "2006-01-02 15:04:05"}} | ||
This report was generated by [DevQualityEval benchmark](https://github.com/symflower/eval-dev-quality) in ` + "`" + `version {{.Version}}` + "`" + `. | ||
## Results | ||
> Keep in mind that LLMs are nondeterministic. The following results just reflect a current snapshot. | ||
The results of all models have been divided into the following categories: | ||
{{ range $category := .Categories -}} | ||
- {{ $category.Name }}: {{ $category.Description }} | ||
{{ end }} | ||
The following sections list all models with their categories. The complete log of the evaluation with all outputs can be found [here]({{.LogPath}}). Detailed scoring can be found [here]({{.CSVPath}}). | ||
{{ range $category := .Categories -}} | ||
{{ with $modelNames := index $.ModelsPerCategory $category -}} | ||
### "{{ $category.Name }}" | ||
{{ $category.Description }} | ||
{{ range $modelName := $modelNames -}} | ||
- ` + "`" + `{{ $modelName }}` + "`" + ` | ||
{{ end }} | ||
{{ end }} | ||
{{- end -}} | ||
`))) | ||
|
||
// Format formats the markdown values in the template to the given writer. | ||
func (m Markdown) Format(writer io.Writer) error { | ||
templateContext := markdownTemplateContext{ | ||
Markdown: m, | ||
Categories: metrics.AllAssessmentCategories, | ||
} | ||
templateContext.ModelsPerCategory = make(map[*metrics.AssessmentCategory][]string, len(metrics.AllAssessmentCategories)) | ||
for model, assessment := range m.AssessmentPerModel { | ||
category := assessment.Category(m.TotalScore) | ||
templateContext.ModelsPerCategory[category] = append(templateContext.ModelsPerCategory[category], model) | ||
} | ||
// TODO Generate svg using maybe https://github.com/wcharczuk/go-chart. | ||
|
||
return pkgerrors.WithStack(markdownTemplate.Execute(writer, templateContext)) | ||
} | ||
|
||
// WriteToFile writes the Markdown values in the template to the given file. | ||
func (t Markdown) WriteToFile(path string) (err error) { | ||
t.CSVPath, err = filepath.Abs(t.CSVPath) | ||
if err != nil { | ||
return err | ||
} | ||
t.LogPath, err = filepath.Abs(t.LogPath) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if err = os.MkdirAll(filepath.Base(path), 0755); err != nil { | ||
return pkgerrors.WithStack(err) | ||
} | ||
file, err := os.Create(path) | ||
if err != nil { | ||
return pkgerrors.WithStack(err) | ||
} | ||
|
||
return pkgerrors.WithStack(t.Format(file)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package report | ||
|
||
import ( | ||
"bytes" | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
"github.com/symflower/eval-dev-quality/evaluate/metrics" | ||
"github.com/zimmski/osutil/bytesutil" | ||
) | ||
|
||
func TestMarkdownFormat(t *testing.T) { | ||
type testCase struct { | ||
Name string | ||
|
||
Markdown Markdown | ||
|
||
ExpectedReport string | ||
ExpectedError error | ||
} | ||
|
||
validate := func(t *testing.T, tc *testCase) { | ||
t.Run(tc.Name, func(t *testing.T) { | ||
var buffer bytes.Buffer | ||
actualError := tc.Markdown.Format(&buffer) | ||
assert.Equal(t, tc.ExpectedError, actualError) | ||
actualReport := buffer.String() | ||
|
||
assert.Equalf(t, bytesutil.StringTrimIndentations(tc.ExpectedReport), actualReport, "Full output:\n%s", actualReport) | ||
}) | ||
} | ||
|
||
testTimeString := "2000-01-01 00:00:00" | ||
testTime, err := time.Parse(time.DateTime, testTimeString) | ||
require.NoError(t, err) | ||
|
||
validate(t, &testCase{ | ||
Name: "No Models", | ||
|
||
Markdown: Markdown{ | ||
DateTime: testTime, | ||
Version: "1234", | ||
|
||
CSVPath: "some/csv/path.csv", | ||
LogPath: "some/log/path.log", | ||
}, | ||
|
||
ExpectedReport: ` | ||
# Evaluation from 2000-01-01 00:00:00 | ||
This report was generated by [DevQualityEval benchmark](https://github.com/symflower/eval-dev-quality) in ` + "`" + `version 1234` + "`" + `. | ||
## Results | ||
> Keep in mind that LLMs are nondeterministic. The following results just reflect a current snapshot. | ||
The results of all models have been divided into the following categories: | ||
- Category Unknown: Models in this category could not be categorized. | ||
- Response Error: Models in this category encountered an error. | ||
- Response Empty: Models in this category produced an empty response. | ||
- No Code: Models in this category produced no code. | ||
- Invalid Code: Models in this category produced invalid code. | ||
- Executable Code: Models in this category produced executable code. | ||
- Statement Coverage Reached: Models in this category produced code that reached full statement coverage. | ||
- No Excess Response: Models in this category did not respond with more content than requested. | ||
The following sections list all models with their categories. The complete log of the evaluation with all outputs can be found [here](some/log/path.log). Detailed scoring can be found [here](some/csv/path.csv). | ||
`, | ||
}) | ||
|
||
validate(t, &testCase{ | ||
Name: "Simple Models", | ||
|
||
Markdown: Markdown{ | ||
DateTime: testTime, | ||
Version: "1234", | ||
|
||
CSVPath: "some/csv/path.csv", | ||
LogPath: "some/log/path.log", | ||
|
||
TotalScore: 1, | ||
AssessmentPerModel: map[string]metrics.Assessments{ | ||
"ModelResponseError": metrics.NewAssessments(), | ||
"ModelNoCode": metrics.Assessments{ | ||
metrics.AssessmentKeyResponseNoError: 1, | ||
metrics.AssessmentKeyResponseNotEmpty: 1, | ||
}, | ||
}, | ||
}, | ||
|
||
ExpectedReport: ` | ||
# Evaluation from 2000-01-01 00:00:00 | ||
This report was generated by [DevQualityEval benchmark](https://github.com/symflower/eval-dev-quality) in ` + "`" + `version 1234` + "`" + `. | ||
## Results | ||
> Keep in mind that LLMs are nondeterministic. The following results just reflect a current snapshot. | ||
The results of all models have been divided into the following categories: | ||
- Category Unknown: Models in this category could not be categorized. | ||
- Response Error: Models in this category encountered an error. | ||
- Response Empty: Models in this category produced an empty response. | ||
- No Code: Models in this category produced no code. | ||
- Invalid Code: Models in this category produced invalid code. | ||
- Executable Code: Models in this category produced executable code. | ||
- Statement Coverage Reached: Models in this category produced code that reached full statement coverage. | ||
- No Excess Response: Models in this category did not respond with more content than requested. | ||
The following sections list all models with their categories. The complete log of the evaluation with all outputs can be found [here](some/log/path.log). Detailed scoring can be found [here](some/csv/path.csv). | ||
### "Response Error" | ||
Models in this category encountered an error. | ||
- ` + "`ModelResponseError`" + ` | ||
### "No Code" | ||
Models in this category produced no code. | ||
- ` + "`ModelNoCode`" + ` | ||
`, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package version | ||
|
||
// Current holds the current version. | ||
var Current = "0.2.0" |