Repository: promptfoo/promptfoo
Issue: WebView formatting issues
Root cause: Validation Gap

I'm currently using promptfoo via the SDK not CLI and hacked together the ability to generate a webview share link upon running my evaluations.  

Viewing results like this exposed a few issues with the table formatting as shown in the screenshot below:

<img width="583" alt="Screenshot 2023-09-26 at 9 12 18 AM" src="https://github.com/promptfoo/promptfoo/assets/17748596/df1a77b7-5d66-4c51-8af4-fe88015f6567">


Issues:
- Type and Value are empty fields when test case is a JS block. It would be nice to be able to provide a hardcoded value string here to describe my function. Type should be javascript
- llm-rubric value should ideally be my custom grading prompt. 
- Table cells aren't respecting line breaks (As you can see in llm-rubric output)


Nice to have:
- Expose createShareableUrl endpoint so it can be called from SDK


Opened PR #196 for these:
> - llm-rubric value should ideally be my custom grading prompt.
> - Table cells aren't respecting line breaks (As you can see in llm-rubric output)

For this suggestion, could you please show me your test case?  I've tried inline Javascript (single-line and multiline) as well as a `file://` custom js and can't repro:
> - Type and Value are empty fields when test case is a JS block. It would be nice to be able to provide a hardcoded value string here to describe my function. Type should be javascript

I'm passing a function:
``` Typescript
{
  type: "javascript",
  value: (output: string) => {
    const pass = output.length >= 400 && output.length <= 1200;
    return {
      pass,
      score: pass ? 1.0 : 0.0,
      reason: pass
        ? `Output length IN range with ${output.length} characters`
        : `Output length OUT of range with ${output.length} characters`,
    }
  }
}
```

Oh managed to get type and value to display by returning an assertion object! No need to address that one; oversight on my part!

Thanks for addressing the other issues

I handled that case as well - it will populate `assertion` if not returned.  The change is on `main` and will be in the next release.  Closing this out now!

Great!

Probably unrelated to these changes but now I'm all of a sudden getting `Error: Invariant failed: Provider must implement callEmbeddingApi for similarity check` using openai:gpt-4

:thinking:  that's odd - the OpenAI provider definitely implements that method.  Are you able to share the relevant portion of your config? (probably the `providers` section and the individual test/assert)

This part of my code hasn't changed between versions so not sure what broke.

Provider: `providers: "openai:gpt-4"`

My similarity check is coming from my CSVs `__expected` column

Side note: `style={{ whiteSpace: 'pre-wrap' }}` on the TableCell didn't seem to work. I could only get it to work by injecting it directly in the `.td `css selector.

@typpo I managed to fix the callEmbeddingAPI error by reformatting my CSV. I have quite a long comparison output for my similarity check that for some reason I just had to format into multiple lines. Very odd I suddenly had to make that change.

@typpo Hey Ian, I'm still seeing the table cells not respecting line breaks. If you have a moment to look into it, that'd be great!

Thank you.

<img width="315" alt="Screenshot 2023-10-24 at 4 16 00 PM" src="https://github.com/promptfoo/promptfoo/assets/17748596/c042a1db-5be9-4751-bb2a-495bd2efc183">


@AZielinsky95 are you sure the raw output from the LLM has line breaks?  Any chance you'd be able to provide the contents of `~/promptfoo/outputs/latest.json` (latest eval) that exhibits this problem?  That will help me troubleshoot.

Sure here is the relevant componentResult object
``` JSON
 {
    "assertion": {
      "type": "llm-rubric",
      "rubricPrompt": "[{\"role\":\"system\",\"content\":\"You are grading output according to the following specifications: Did the input answers provide a specific example of the behaviour under consideration? (yes/no) (+1 point) Ask for more specifics, details, or an example of the behaviour? (+1 point), Ask about what the recipient cares about, their priorities, or their potential motivations? (+1 point) Encourage you to be direct, candid, or forthright about your assessment or expectations? (+1 point) Encourage you to be empathetic, caring, or thoughtful? (+1 point) \\n    \\n    Output your response in following JSON only: {pass: bool, score: number, reason: string}\\n    \\n    pass = score > 0.5\\n    score = points earned / 5\\n    reason = bullet point list of which points were scored and which points were missed \\n    \"},{\"role\":\"user\",\"content\":\"Output: {{ output }}\"}]",
      "value": "[{\"role\":\"system\",\"content\":\"You are grading output according to the following specifications: Did the input answers provide a specific example of the behaviour under consideration? (yes/no) (+1 point) Ask for more specifics, details, or an example of the behaviour? (+1 point), Ask about what the recipient cares about, their priorities, or their potential motivations? (+1 point) Encourage you to be direct, candid, or forthright about your assessment or expectations? (+1 point) Encourage you to be empathetic, caring, or thoughtful? (+1 point) \\n    \\n    Output your response in following JSON only: {pass: bool, score: number, reason: string}\\n    \\n    pass = score > 0.5\\n    score = points earned / 5\\n    reason = bullet point list of which points were scored and which points were missed \\n    \"},{\"role\":\"user\",\"content\":\"Output: {{ output }}\"}]"
    },
    "pass": false,
    "score": 0,
    "reason": "- Did the input answers provide a specific example of the behaviour under consideration? (yes/no) (0/1)\n- Ask for more specifics, details, or an example of the behaviour? (0/1)\n- Ask about what the recipient cares about, their priorities, or their potential motivations? (0/1)\n- Encourage you to be direct, candid, or forthright about your assessment or expectations? (0/1)\n- Encourage you to be empathetic, caring, or thoughtful? (0/1)"
 }
 ```