From a0d9f2dde2b9f13bfca3ccfc0bdd8084f6e89948 Mon Sep 17 00:00:00 2001 From: Seth Juarez Date: Tue, 4 Aug 2026 00:22:58 -0700 Subject: [PATCH 01/10] feat(schema): classify stream failures Add canonical determinate and indeterminate stream failure chunks, regenerate every configured model target, and define shared behavior vectors while retaining ErrorChunk compatibility. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../events/FailureChunkConversionTests.cs | 11 + .../events/StreamFailureConversionTests.cs | 123 ++++++++++ .../Prompty.Core/Model/events/FailureChunk.cs | 165 +++++++++++++ .../Prompty.Core/Model/events/StreamChunk.cs | 1 + .../Model/events/StreamFailure.cs | 169 +++++++++++++ .../Model/events/StreamFailureOutcome.cs | 42 ++++ .../go/prompty/model/failure_chunk_test.go | 4 + runtime/go/prompty/model/stream_chunk.go | 80 +++++++ runtime/go/prompty/model/stream_failure.go | 90 +++++++ .../go/prompty/model/stream_failure_test.go | 225 ++++++++++++++++++ .../python/prompty/prompty/model/__init__.py | 4 + .../prompty/model/events/_StreamChunk.py | 95 ++++++++ .../prompty/model/events/_StreamFailure.py | 107 +++++++++ .../prompty/prompty/model/events/__init__.py | 4 + .../tests/model/events/test_stream_failure.py | 82 +++++++ runtime/rust/prompty/src/model/events/mod.rs | 3 + .../prompty/src/model/events/stream_chunk.rs | 21 ++ .../src/model/events/stream_failure.rs | 167 +++++++++++++ .../rust/prompty/tests/model/events/mod.rs | 1 + .../tests/model/events/stream_failure_test.rs | 105 ++++++++ .../packages/core/src/model/events/index.ts | 2 + .../core/src/model/events/stream-chunk.ts | 91 +++++++ .../core/src/model/events/stream-failure.ts | 92 +++++++ .../packages/core/src/model/index.ts | 2 + .../tests/model/events/failure-chunk.test.ts | 34 +++ .../tests/model/events/stream-failure.test.ts | 72 ++++++ schema/model/events/stream-chunks.tsp | 37 ++- .../.typra-generated/export-surfaces.json | 118 +++++++++ .../tsp-output/.typra-generated/manifest.json | 85 +++++++ .../process/stream_failure_vectors.json | 80 +++++++ vscode/prompty/schemas/FailureChunk.yaml | 17 ++ vscode/prompty/schemas/StreamChunk.yaml | 2 + vscode/prompty/schemas/StreamFailure.yaml | 18 ++ .../content/docs/reference/FailureChunk.md | 49 ++++ web/src/content/docs/reference/StreamChunk.md | 6 + .../content/docs/reference/StreamFailure.md | 40 ++++ 36 files changed, 2243 insertions(+), 1 deletion(-) create mode 100644 runtime/csharp/Prompty.Core.Tests/Model/events/FailureChunkConversionTests.cs create mode 100644 runtime/csharp/Prompty.Core.Tests/Model/events/StreamFailureConversionTests.cs create mode 100644 runtime/csharp/Prompty.Core/Model/events/FailureChunk.cs create mode 100644 runtime/csharp/Prompty.Core/Model/events/StreamFailure.cs create mode 100644 runtime/csharp/Prompty.Core/Model/events/StreamFailureOutcome.cs create mode 100644 runtime/go/prompty/model/failure_chunk_test.go create mode 100644 runtime/go/prompty/model/stream_failure.go create mode 100644 runtime/go/prompty/model/stream_failure_test.go create mode 100644 runtime/python/prompty/prompty/model/events/_StreamFailure.py create mode 100644 runtime/python/prompty/tests/model/events/test_stream_failure.py create mode 100644 runtime/rust/prompty/src/model/events/stream_failure.rs create mode 100644 runtime/rust/prompty/tests/model/events/stream_failure_test.rs create mode 100644 runtime/typescript/packages/core/src/model/events/stream-failure.ts create mode 100644 runtime/typescript/packages/core/tests/model/events/failure-chunk.test.ts create mode 100644 runtime/typescript/packages/core/tests/model/events/stream-failure.test.ts create mode 100644 spec/vectors/process/stream_failure_vectors.json create mode 100644 vscode/prompty/schemas/FailureChunk.yaml create mode 100644 vscode/prompty/schemas/StreamFailure.yaml create mode 100644 web/src/content/docs/reference/FailureChunk.md create mode 100644 web/src/content/docs/reference/StreamFailure.md diff --git a/runtime/csharp/Prompty.Core.Tests/Model/events/FailureChunkConversionTests.cs b/runtime/csharp/Prompty.Core.Tests/Model/events/FailureChunkConversionTests.cs new file mode 100644 index 000000000..ff7ebd431 --- /dev/null +++ b/runtime/csharp/Prompty.Core.Tests/Model/events/FailureChunkConversionTests.cs @@ -0,0 +1,11 @@ +// +using Xunit; + +#pragma warning disable IDE0130 +namespace Prompty.Core; +#pragma warning restore IDE0130 + + +public class FailureChunkConversionTests +{ +} diff --git a/runtime/csharp/Prompty.Core.Tests/Model/events/StreamFailureConversionTests.cs b/runtime/csharp/Prompty.Core.Tests/Model/events/StreamFailureConversionTests.cs new file mode 100644 index 000000000..d5161bb16 --- /dev/null +++ b/runtime/csharp/Prompty.Core.Tests/Model/events/StreamFailureConversionTests.cs @@ -0,0 +1,123 @@ +// +using Xunit; + +#pragma warning disable IDE0130 +namespace Prompty.Core; +#pragma warning restore IDE0130 + + +public class StreamFailureConversionTests +{ + [Fact] + public void LoadYamlInput() + { + string yamlData = """ +outcome: indeterminate +message: "SSE stream error: connection reset" + +"""; + + var instance = StreamFailure.FromYaml(yamlData); + + Assert.NotNull(instance); + Assert.Equal(StreamFailureOutcome.Indeterminate, instance.Outcome); + Assert.Equal("SSE stream error: connection reset", instance.Message); + } + + [Fact] + public void LoadJsonInput() + { + string jsonData = """ +{ + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" +} +"""; + + var instance = StreamFailure.FromJson(jsonData); + Assert.NotNull(instance); + Assert.Equal(StreamFailureOutcome.Indeterminate, instance.Outcome); + Assert.Equal("SSE stream error: connection reset", instance.Message); + } + + [Fact] + public void RoundtripJson() + { + // Test that FromJson -> ToJson -> FromJson produces equivalent data + string jsonData = """ +{ + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" +} +"""; + + var original = StreamFailure.FromJson(jsonData); + Assert.NotNull(original); + + var json = original.ToJson(); + Assert.False(string.IsNullOrEmpty(json)); + + var reloaded = StreamFailure.FromJson(json); + Assert.NotNull(reloaded); + Assert.Equal(StreamFailureOutcome.Indeterminate, reloaded.Outcome); + Assert.Equal("SSE stream error: connection reset", reloaded.Message); + } + + [Fact] + public void RoundtripYaml() + { + // Test that FromYaml -> ToYaml -> FromYaml produces equivalent data + string yamlData = """ +outcome: indeterminate +message: "SSE stream error: connection reset" + +"""; + + var original = StreamFailure.FromYaml(yamlData); + Assert.NotNull(original); + + var yaml = original.ToYaml(); + Assert.False(string.IsNullOrEmpty(yaml)); + + var reloaded = StreamFailure.FromYaml(yaml); + Assert.NotNull(reloaded); + Assert.Equal(StreamFailureOutcome.Indeterminate, reloaded.Outcome); + Assert.Equal("SSE stream error: connection reset", reloaded.Message); + } + + [Fact] + public void ToJsonProducesValidJson() + { + string jsonData = """ +{ + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" +} +"""; + + var instance = StreamFailure.FromJson(jsonData); + var json = instance.ToJson(); + + // Verify it's valid JSON by parsing it + var parsed = System.Text.Json.JsonDocument.Parse(json); + Assert.NotNull(parsed); + } + + [Fact] + public void ToYamlProducesValidYaml() + { + string yamlData = """ +outcome: indeterminate +message: "SSE stream error: connection reset" + +"""; + + var instance = StreamFailure.FromYaml(yamlData); + var yaml = instance.ToYaml(); + + // Verify it's valid YAML by parsing it + var deserializer = new YamlDotNet.Serialization.DeserializerBuilder().Build(); + var parsed = deserializer.Deserialize(yaml); + Assert.NotNull(parsed); + } +} diff --git a/runtime/csharp/Prompty.Core/Model/events/FailureChunk.cs b/runtime/csharp/Prompty.Core/Model/events/FailureChunk.cs new file mode 100644 index 000000000..7da9b9ac6 --- /dev/null +++ b/runtime/csharp/Prompty.Core/Model/events/FailureChunk.cs @@ -0,0 +1,165 @@ +// +// Copyright (c) Microsoft. All rights reserved. +using System.Text.Json; +using YamlDotNet.Serialization; + +#pragma warning disable IDE0130 +namespace Prompty.Core; +#pragma warning restore IDE0130 + + /// + /// A classified failure chunk from the LLM response stream. + /// +public partial class FailureChunk : StreamChunk +{ + /// + /// The shorthand property name for this type, if any. + /// + public new static string? ShorthandProperty => null; + + /// + /// Initializes a new instance of . + /// +#pragma warning disable CS8618 + public FailureChunk() + { + } +#pragma warning restore CS8618 + + /// + /// The kind identifier for classified failure chunks + /// + public override string Kind { get; set; } = "failure"; + + /// + /// The classified stream failure + /// + public StreamFailure Failure { get; set; } + + + + #region Load Methods + + /// + /// Load a FailureChunk instance from a dictionary. + /// + /// The dictionary containing the data. + /// Optional context with pre/post processing callbacks. + /// The loaded FailureChunk instance. + public new static FailureChunk Load(Dictionary data, LoadContext? context = null) + { + if (context is not null) + { + data = context.ProcessInput(data); + } + + + // Create new instance + var instance = new FailureChunk(); + + + if (data.TryGetValue("kind", out var kindValue) && kindValue is not null) + { + instance.Kind = kindValue?.ToString()!; + } + + if (data.TryGetValue("failure", out var failureValue) && failureValue is not null) + { + instance.Failure = StreamFailure.Load(failureValue.GetDictionary(StreamFailure.ShorthandProperty), context); + } + + if (context is not null) + { + instance = context.ProcessOutput(instance); + } + return instance; + } + + + #endregion + + #region Save Methods + + /// + /// Save the FailureChunk instance to a dictionary. + /// + /// Optional context with pre/post processing callbacks. + /// The dictionary representation of this instance. + public override Dictionary Save(SaveContext? context = null) + { + var obj = this; + if (context is not null) + { + obj = context.ProcessObject(obj); + } + + + // Start with parent class properties + var result = base.Save(context); + + + result["kind"] = obj.Kind; + + + result["failure"] = obj.Failure?.Save(context); + + + return result; + } + + + /// + /// Convert the FailureChunk instance to a YAML string. + /// + /// Optional context with pre/post processing callbacks. + /// The YAML string representation of this instance. + public new string ToYaml(SaveContext? context = null) + { + context ??= new SaveContext(); + return context.ToYaml(Save(context)); + } + + /// + /// Convert the FailureChunk instance to a JSON string. + /// + /// Optional context with pre/post processing callbacks. + /// Whether to indent the output. Defaults to true. + /// The JSON string representation of this instance. + public new string ToJson(SaveContext? context = null, bool indent = true) + { + context ??= new SaveContext(); + return context.ToJson(Save(context), indent); + } + + /// + /// Load a FailureChunk instance from a JSON string. + /// + /// The JSON string to parse. + /// Optional context with pre/post processing callbacks. + /// The loaded FailureChunk instance. + public new static FailureChunk FromJson(string json, LoadContext? context = null) + { + using var doc = JsonDocument.Parse(json); + Dictionary dict; + dict = JsonSerializer.Deserialize>(json, JsonUtils.Options) + ?? throw new ArgumentException("Failed to parse JSON as dictionary"); + + return Load(dict, context); + } + + /// + /// Load a FailureChunk instance from a YAML string. + /// + /// The YAML string to parse. + /// Optional context with pre/post processing callbacks. + /// The loaded FailureChunk instance. + public new static FailureChunk FromYaml(string yaml, LoadContext? context = null) + { + var dict = YamlUtils.Deserializer.Deserialize>(yaml) + ?? throw new ArgumentException("Failed to parse YAML as dictionary"); + + return Load(dict, context); + } + + #endregion +} diff --git a/runtime/csharp/Prompty.Core/Model/events/StreamChunk.cs b/runtime/csharp/Prompty.Core/Model/events/StreamChunk.cs index 579741cd0..9934cdc92 100644 --- a/runtime/csharp/Prompty.Core/Model/events/StreamChunk.cs +++ b/runtime/csharp/Prompty.Core/Model/events/StreamChunk.cs @@ -83,6 +83,7 @@ private static StreamChunk LoadKind(Dictionary data, LoadContex "tool" => ToolChunk.Load(data, context), "usage" => UsageChunk.Load(data, context), "error" => ErrorChunk.Load(data, context), + "failure" => FailureChunk.Load(data, context), _ => throw new ArgumentException($"Unknown StreamChunk discriminator value: {discriminator}"), }; } diff --git a/runtime/csharp/Prompty.Core/Model/events/StreamFailure.cs b/runtime/csharp/Prompty.Core/Model/events/StreamFailure.cs new file mode 100644 index 000000000..eaaa38521 --- /dev/null +++ b/runtime/csharp/Prompty.Core/Model/events/StreamFailure.cs @@ -0,0 +1,169 @@ +// +// Copyright (c) Microsoft. All rights reserved. +using System.Text.Json; +using YamlDotNet.Serialization; + +#pragma warning disable IDE0130 +namespace Prompty.Core; +#pragma warning restore IDE0130 + + /// + /// A classified terminal failure from an LLM response stream. + /// +public partial class StreamFailure +{ + /// + /// The shorthand property name for this type, if any. + /// + public static string? ShorthandProperty => null; + + /// + /// Initializes a new instance of . + /// +#pragma warning disable CS8618 + public StreamFailure() + { + } +#pragma warning restore CS8618 + + /// + /// Whether the provider outcome is known or requires reconciliation + /// + public StreamFailureOutcome Outcome { get; set; } = StreamFailureOutcome.Determinate; + + /// + /// The human-readable failure message + /// + public string Message { get; set; } = string.Empty; + + + + #region Load Methods + + /// + /// Load a StreamFailure instance from a dictionary. + /// + /// The dictionary containing the data. + /// Optional context with pre/post processing callbacks. + /// The loaded StreamFailure instance. + public static StreamFailure Load(Dictionary data, LoadContext? context = null) + { + if (context is not null) + { + data = context.ProcessInput(data); + } + + + // Create new instance + var instance = new StreamFailure(); + + + if (data.TryGetValue("outcome", out var outcomeValue) && outcomeValue is not null) + { + instance.Outcome = StreamFailureOutcomeParser.Parse(outcomeValue?.ToString()!); + } + + if (data.TryGetValue("message", out var messageValue) && messageValue is not null) + { + instance.Message = messageValue?.ToString()!; + } + + if (context is not null) + { + instance = context.ProcessOutput(instance); + } + return instance; + } + + + #endregion + + #region Save Methods + + /// + /// Save the StreamFailure instance to a dictionary. + /// + /// Optional context with pre/post processing callbacks. + /// The dictionary representation of this instance. + public Dictionary Save(SaveContext? context = null) + { + var obj = this; + if (context is not null) + { + obj = context.ProcessObject(obj); + } + + + var result = new Dictionary(); + + + result["outcome"] = StreamFailureOutcomeParser.ToValue(obj.Outcome); + + + result["message"] = obj.Message; + + + if (context is not null) + { + result = context.ProcessDict(result); + } + + return result; + } + + + /// + /// Convert the StreamFailure instance to a YAML string. + /// + /// Optional context with pre/post processing callbacks. + /// The YAML string representation of this instance. + public string ToYaml(SaveContext? context = null) + { + context ??= new SaveContext(); + return context.ToYaml(Save(context)); + } + + /// + /// Convert the StreamFailure instance to a JSON string. + /// + /// Optional context with pre/post processing callbacks. + /// Whether to indent the output. Defaults to true. + /// The JSON string representation of this instance. + public string ToJson(SaveContext? context = null, bool indent = true) + { + context ??= new SaveContext(); + return context.ToJson(Save(context), indent); + } + + /// + /// Load a StreamFailure instance from a JSON string. + /// + /// The JSON string to parse. + /// Optional context with pre/post processing callbacks. + /// The loaded StreamFailure instance. + public static StreamFailure FromJson(string json, LoadContext? context = null) + { + using var doc = JsonDocument.Parse(json); + Dictionary dict; + dict = JsonSerializer.Deserialize>(json, JsonUtils.Options) + ?? throw new ArgumentException("Failed to parse JSON as dictionary"); + + return Load(dict, context); + } + + /// + /// Load a StreamFailure instance from a YAML string. + /// + /// The YAML string to parse. + /// Optional context with pre/post processing callbacks. + /// The loaded StreamFailure instance. + public static StreamFailure FromYaml(string yaml, LoadContext? context = null) + { + var dict = YamlUtils.Deserializer.Deserialize>(yaml) + ?? throw new ArgumentException("Failed to parse YAML as dictionary"); + + return Load(dict, context); + } + + #endregion +} diff --git a/runtime/csharp/Prompty.Core/Model/events/StreamFailureOutcome.cs b/runtime/csharp/Prompty.Core/Model/events/StreamFailureOutcome.cs new file mode 100644 index 000000000..4c3f269e9 --- /dev/null +++ b/runtime/csharp/Prompty.Core/Model/events/StreamFailureOutcome.cs @@ -0,0 +1,42 @@ +// +// +// Code generated by Typra emitter; DO NOT EDIT. + +using System; +using System.Text.Json.Serialization; + +namespace Prompty.Core; + +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum StreamFailureOutcome +{ + [JsonPropertyName("determinate")] + Determinate, + + [JsonPropertyName("indeterminate")] + Indeterminate, + +} + +public static class StreamFailureOutcomeParser +{ + public static StreamFailureOutcome Parse(string value) + { + return value switch + { + "determinate" => StreamFailureOutcome.Determinate, + "indeterminate" => StreamFailureOutcome.Indeterminate, + _ => Enum.Parse(value, true), + }; + } + + public static string ToValue(StreamFailureOutcome value) + { + return value switch + { + StreamFailureOutcome.Determinate => "determinate", + StreamFailureOutcome.Indeterminate => "indeterminate", + _ => value.ToString().ToLowerInvariant(), + }; + } +} diff --git a/runtime/go/prompty/model/failure_chunk_test.go b/runtime/go/prompty/model/failure_chunk_test.go new file mode 100644 index 000000000..9cc5440c4 --- /dev/null +++ b/runtime/go/prompty/model/failure_chunk_test.go @@ -0,0 +1,4 @@ +// +// Code generated by Typra emitter; DO NOT EDIT. + +package prompty_test diff --git a/runtime/go/prompty/model/stream_chunk.go b/runtime/go/prompty/model/stream_chunk.go index 6d8a215d5..954cb7da1 100644 --- a/runtime/go/prompty/model/stream_chunk.go +++ b/runtime/go/prompty/model/stream_chunk.go @@ -39,6 +39,8 @@ func LoadStreamChunk(data interface{}, ctx *LoadContext) (interface{}, error) { return LoadUsageChunk(data, ctx) case "error": return LoadErrorChunk(data, ctx) + case "failure": + return LoadFailureChunk(data, ctx) default: return nil, fmt.Errorf("unknown StreamChunk discriminator value: %s", discriminator) } @@ -474,3 +476,81 @@ func ErrorChunkFromYAML(yamlStr string) (ErrorChunk, error) { ctx := NewLoadContext() return LoadErrorChunk(data, ctx) } + +// FailureChunk represents A classified failure chunk from the LLM response stream. + +type FailureChunk struct { + Kind string `json:"kind" yaml:"kind"` + Failure StreamFailure `json:"failure" yaml:"failure"` +} + +// LoadFailureChunk creates a FailureChunk from a map[string]interface{} +func LoadFailureChunk(data interface{}, ctx *LoadContext) (FailureChunk, error) { + result := FailureChunk{} + + // Load from map + if m, ok := data.(map[string]interface{}); ok { + if val, ok := m["kind"]; ok && val != nil { + result.Kind = string(val.(string)) + } + if val, ok := m["failure"]; ok && val != nil { + if m, ok := val.(map[string]interface{}); ok { + loaded, err := LoadStreamFailure(m, ctx) + if err != nil { + return result, err + } + result.Failure = loaded + } + } + } + + return result, nil +} + +// Save serializes FailureChunk to map[string]interface{} +func (obj FailureChunk) Save(ctx *SaveContext) map[string]interface{} { + result := make(map[string]interface{}) + result["kind"] = obj.Kind + + result["failure"] = obj.Failure.Save(ctx) + + return result +} + +// ToJSON serializes FailureChunk to JSON string +func (obj *FailureChunk) ToJSON() (string, error) { + ctx := NewSaveContext() + data := obj.Save(ctx) + bytes, err := json.Marshal(data) + if err != nil { + return "", err + } + return string(bytes), nil +} + +// ToYAML serializes FailureChunk to YAML string +func (obj *FailureChunk) ToYAML() (string, error) { + ctx := NewSaveContext() + data := obj.Save(ctx) + return marshalYAMLDocument(data) +} + +// FromJSON creates FailureChunk from JSON string +func FailureChunkFromJSON(jsonStr string) (FailureChunk, error) { + var data map[string]interface{} + if err := json.Unmarshal([]byte(jsonStr), &data); err != nil { + return FailureChunk{}, err + } + ctx := NewLoadContext() + return LoadFailureChunk(data, ctx) +} + +// FromYAML creates FailureChunk from YAML string +func FailureChunkFromYAML(yamlStr string) (FailureChunk, error) { + var data map[string]interface{} + if err := yaml.Unmarshal([]byte(yamlStr), &data); err != nil { + return FailureChunk{}, err + } + ctx := NewLoadContext() + return LoadFailureChunk(data, ctx) +} diff --git a/runtime/go/prompty/model/stream_failure.go b/runtime/go/prompty/model/stream_failure.go new file mode 100644 index 000000000..f69a03c8a --- /dev/null +++ b/runtime/go/prompty/model/stream_failure.go @@ -0,0 +1,90 @@ +// +// Code generated by Typra emitter; DO NOT EDIT. +// Group: events + +package prompty + +import ( + "encoding/json" + + "gopkg.in/yaml.v3" +) + +// StreamFailureOutcome represents the allowed values for StreamFailureOutcome. +type StreamFailureOutcome string + +const ( + StreamFailureOutcomeDeterminate StreamFailureOutcome = "determinate" + StreamFailureOutcomeIndeterminate StreamFailureOutcome = "indeterminate" +) + +// StreamFailure represents A classified terminal failure from an LLM response stream. + +type StreamFailure struct { + Outcome StreamFailureOutcome `json:"outcome" yaml:"outcome"` + Message string `json:"message" yaml:"message"` +} + +// LoadStreamFailure creates a StreamFailure from a map[string]interface{} +func LoadStreamFailure(data interface{}, ctx *LoadContext) (StreamFailure, error) { + result := StreamFailure{} + + // Load from map + if m, ok := data.(map[string]interface{}); ok { + if val, ok := m["outcome"]; ok && val != nil { + result.Outcome = StreamFailureOutcome(val.(string)) + } + if val, ok := m["message"]; ok && val != nil { + result.Message = string(val.(string)) + } + } + + return result, nil +} + +// Save serializes StreamFailure to map[string]interface{} +func (obj StreamFailure) Save(ctx *SaveContext) map[string]interface{} { + result := make(map[string]interface{}) + result["outcome"] = string(obj.Outcome) + result["message"] = obj.Message + + return result +} + +// ToJSON serializes StreamFailure to JSON string +func (obj *StreamFailure) ToJSON() (string, error) { + ctx := NewSaveContext() + data := obj.Save(ctx) + bytes, err := json.Marshal(data) + if err != nil { + return "", err + } + return string(bytes), nil +} + +// ToYAML serializes StreamFailure to YAML string +func (obj *StreamFailure) ToYAML() (string, error) { + ctx := NewSaveContext() + data := obj.Save(ctx) + return marshalYAMLDocument(data) +} + +// FromJSON creates StreamFailure from JSON string +func StreamFailureFromJSON(jsonStr string) (StreamFailure, error) { + var data map[string]interface{} + if err := json.Unmarshal([]byte(jsonStr), &data); err != nil { + return StreamFailure{}, err + } + ctx := NewLoadContext() + return LoadStreamFailure(data, ctx) +} + +// FromYAML creates StreamFailure from YAML string +func StreamFailureFromYAML(yamlStr string) (StreamFailure, error) { + var data map[string]interface{} + if err := yaml.Unmarshal([]byte(yamlStr), &data); err != nil { + return StreamFailure{}, err + } + ctx := NewLoadContext() + return LoadStreamFailure(data, ctx) +} diff --git a/runtime/go/prompty/model/stream_failure_test.go b/runtime/go/prompty/model/stream_failure_test.go new file mode 100644 index 000000000..1e4caad66 --- /dev/null +++ b/runtime/go/prompty/model/stream_failure_test.go @@ -0,0 +1,225 @@ +// +// Code generated by Typra emitter; DO NOT EDIT. + +package prompty_test + +import ( + "encoding/json" + "testing" + + "gopkg.in/yaml.v3" + + "prompty/model" +) + +// TestStreamFailureLoadJSON tests loading StreamFailure from JSON +func TestStreamFailureLoadJSON(t *testing.T) { + jsonData := ` +{ + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" +} +` + var data map[string]interface{} + if err := json.Unmarshal([]byte(jsonData), &data); err != nil { + t.Fatalf("Failed to parse JSON: %v", err) + } + + ctx := prompty.NewLoadContext() + instance, err := prompty.LoadStreamFailure(data, ctx) + if err != nil { + t.Fatalf("Failed to load StreamFailure: %v", err) + } + if instance.Outcome != "indeterminate" { + t.Errorf(`Expected Outcome to be "indeterminate", got %v`, instance.Outcome) + } + if instance.Message != "SSE stream error: connection reset" { + t.Errorf(`Expected Message to be "SSE stream error: connection reset", got %v`, instance.Message) + } +} + +// TestStreamFailureLoadYAML tests loading StreamFailure from YAML +func TestStreamFailureLoadYAML(t *testing.T) { + yamlData := ` +outcome: indeterminate +message: "SSE stream error: connection reset" + +` + var data map[string]interface{} + if err := yaml.Unmarshal([]byte(yamlData), &data); err != nil { + t.Fatalf("Failed to parse YAML: %v", err) + } + + ctx := prompty.NewLoadContext() + instance, err := prompty.LoadStreamFailure(data, ctx) + if err != nil { + t.Fatalf("Failed to load StreamFailure: %v", err) + } + if instance.Outcome != "indeterminate" { + t.Errorf(`Expected Outcome to be "indeterminate", got %v`, instance.Outcome) + } + if instance.Message != "SSE stream error: connection reset" { + t.Errorf(`Expected Message to be "SSE stream error: connection reset", got %v`, instance.Message) + } +} + +// TestStreamFailureFromJSON tests loading StreamFailure through the generated JSON helper +func TestStreamFailureFromJSON(t *testing.T) { + jsonData := ` +{ + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" +} +` + + instance, err := prompty.StreamFailureFromJSON(jsonData) + if err != nil { + t.Fatalf("Failed to load StreamFailure from JSON helper: %v", err) + } + if instance.Outcome != "indeterminate" { + t.Errorf(`Expected Outcome to be "indeterminate", got %v`, instance.Outcome) + } + if instance.Message != "SSE stream error: connection reset" { + t.Errorf(`Expected Message to be "SSE stream error: connection reset", got %v`, instance.Message) + } +} + +// TestStreamFailureFromYAML tests loading StreamFailure through the generated YAML helper +func TestStreamFailureFromYAML(t *testing.T) { + yamlData := ` +outcome: indeterminate +message: "SSE stream error: connection reset" + +` + + instance, err := prompty.StreamFailureFromYAML(yamlData) + if err != nil { + t.Fatalf("Failed to load StreamFailure from YAML helper: %v", err) + } + if instance.Outcome != "indeterminate" { + t.Errorf(`Expected Outcome to be "indeterminate", got %v`, instance.Outcome) + } + if instance.Message != "SSE stream error: connection reset" { + t.Errorf(`Expected Message to be "SSE stream error: connection reset", got %v`, instance.Message) + } +} + +// TestStreamFailureRoundtrip tests load -> save -> load produces equivalent data +func TestStreamFailureRoundtrip(t *testing.T) { + jsonData := ` +{ + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" +} +` + var data map[string]interface{} + if err := json.Unmarshal([]byte(jsonData), &data); err != nil { + t.Fatalf("Failed to parse JSON: %v", err) + } + + loadCtx := prompty.NewLoadContext() + instance, err := prompty.LoadStreamFailure(data, loadCtx) + if err != nil { + t.Fatalf("Failed to load StreamFailure: %v", err) + } + saveCtx := prompty.NewSaveContext() + savedData := instance.Save(saveCtx) + + reloaded, err := prompty.LoadStreamFailure(savedData, loadCtx) + if err != nil { + t.Fatalf("Failed to reload StreamFailure: %v", err) + } + if reloaded.Outcome != "indeterminate" { + t.Errorf(`Expected Outcome to be "indeterminate", got %v`, reloaded.Outcome) + } + if reloaded.Message != "SSE stream error: connection reset" { + t.Errorf(`Expected Message to be "SSE stream error: connection reset", got %v`, reloaded.Message) + } +} + +// TestStreamFailureToJSON tests that ToJSON produces valid JSON +func TestStreamFailureToJSON(t *testing.T) { + jsonData := ` +{ + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" +} +` + var data map[string]interface{} + if err := json.Unmarshal([]byte(jsonData), &data); err != nil { + t.Fatalf("Failed to parse JSON: %v", err) + } + + ctx := prompty.NewLoadContext() + instance, err := prompty.LoadStreamFailure(data, ctx) + if err != nil { + t.Fatalf("Failed to load StreamFailure: %v", err) + } + jsonOutput, err := instance.ToJSON() + if err != nil { + t.Fatalf("Failed to convert to JSON: %v", err) + } + + var parsed map[string]interface{} + if err := json.Unmarshal([]byte(jsonOutput), &parsed); err != nil { + t.Fatalf("Failed to parse generated JSON: %v", err) + } + + reloaded, err := prompty.LoadStreamFailure(parsed, ctx) + if err != nil { + t.Fatalf("Failed to reload generated JSON: %v", err) + } + if reloaded.Outcome != "indeterminate" { + t.Errorf(`Expected Outcome to be "indeterminate", got %v`, reloaded.Outcome) + } + if reloaded.Message != "SSE stream error: connection reset" { + t.Errorf(`Expected Message to be "SSE stream error: connection reset", got %v`, reloaded.Message) + } +} + +// TestStreamFailureToYAML tests that ToYAML produces valid YAML +func TestStreamFailureToYAML(t *testing.T) { + jsonData := ` +{ + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" +} +` + var data map[string]interface{} + if err := json.Unmarshal([]byte(jsonData), &data); err != nil { + t.Fatalf("Failed to parse JSON: %v", err) + } + + ctx := prompty.NewLoadContext() + instance, err := prompty.LoadStreamFailure(data, ctx) + if err != nil { + t.Fatalf("Failed to load StreamFailure: %v", err) + } + yamlOutput, err := instance.ToYAML() + if err != nil { + t.Fatalf("Failed to convert to YAML: %v", err) + } + + var parsed map[string]interface{} + if err := yaml.Unmarshal([]byte(yamlOutput), &parsed); err != nil { + t.Fatalf("Failed to parse generated YAML: %v", err) + } + + reloaded, err := prompty.LoadStreamFailure(parsed, ctx) + if err != nil { + t.Fatalf("Failed to reload generated YAML: %v", err) + } + if reloaded.Outcome != "indeterminate" { + t.Errorf(`Expected Outcome to be "indeterminate", got %v`, reloaded.Outcome) + } + if reloaded.Message != "SSE stream error: connection reset" { + t.Errorf(`Expected Message to be "SSE stream error: connection reset", got %v`, reloaded.Message) + } +} + +// TestStreamFailureFromJSONInvalid rejects malformed JSON instead of silently defaulting +func TestStreamFailureFromJSONInvalid(t *testing.T) { + if _, err := prompty.StreamFailureFromJSON("{"); err == nil { + t.Fatalf("Expected malformed JSON to fail") + } +} diff --git a/runtime/python/prompty/prompty/model/__init__.py b/runtime/python/prompty/prompty/model/__init__.py index 57869e118..e5f6d3246 100644 --- a/runtime/python/prompty/prompty/model/__init__.py +++ b/runtime/python/prompty/prompty/model/__init__.py @@ -52,6 +52,7 @@ DoneEventPayload, ErrorChunk, ErrorEventPayload, + FailureChunk, HarnessContext, HookEndPayload, HookStartPayload, @@ -77,6 +78,7 @@ SessionWarningPayload, StatusEventPayload, StreamChunk, + StreamFailure, TextChunk, ThinkingChunk, ThinkingEventPayload, @@ -330,12 +332,14 @@ "PermissionResolver", "CheckpointStore", "HostToolExecutor", + "StreamFailure", "StreamChunk", "TextChunk", "ThinkingChunk", "ToolChunk", "UsageChunk", "ErrorChunk", + "FailureChunk", "StreamOptions", "TraceTime", "TraceSpan", diff --git a/runtime/python/prompty/prompty/model/events/_StreamChunk.py b/runtime/python/prompty/prompty/model/events/_StreamChunk.py index 4a11e3f7c..e3709b9c5 100644 --- a/runtime/python/prompty/prompty/model/events/_StreamChunk.py +++ b/runtime/python/prompty/prompty/model/events/_StreamChunk.py @@ -12,6 +12,7 @@ from .._context import LoadContext, SaveContext from ..conversation._ToolCall import ToolCall from ..model._InvocationUsage import InvocationUsage +from ._StreamFailure import StreamFailure @dataclass @@ -70,6 +71,8 @@ def load_kind(data: dict, context: LoadContext | None) -> "StreamChunk": return UsageChunk.load(data, context) elif discriminator_value == "error": return ErrorChunk.load(data, context) + elif discriminator_value == "failure": + return FailureChunk.load(data, context) else: raise ValueError(f"Unknown StreamChunk discriminator value: {discriminator_value}") @@ -581,3 +584,95 @@ def to_json(self, context: SaveContext | None = None, indent: int = 2) -> str: if context is None: context = SaveContext() return context.to_json(self.save(context), indent) + + +@dataclass +class FailureChunk(StreamChunk): + """A classified failure chunk from the LLM response stream. + + Attributes + ---------- + kind : str + The kind identifier for classified failure chunks + failure : StreamFailure + The classified stream failure + """ + + _shorthand_property: ClassVar[str | None] = None + + kind: str = field(default="failure") + failure: StreamFailure = field(default_factory=StreamFailure) + + @staticmethod + def load(data: Any, context: LoadContext | None = None) -> "FailureChunk": + """Load a FailureChunk instance. + Args: + data (Any): The data to load the instance from. + context (Optional[LoadContext]): Optional context with pre/post processing callbacks. + Returns: + FailureChunk: The loaded FailureChunk instance. + + """ + + if context is not None: + data = context.process_input(data) + + if not isinstance(data, dict): + raise ValueError(f"Invalid data for FailureChunk: {data}") + + # create new instance + instance = FailureChunk() + + if data is not None and "kind" in data: + instance.kind = data["kind"] + if data is not None and "failure" in data: + instance.failure = StreamFailure.load(data["failure"], context) + if context is not None: + instance = context.process_output(instance) + return instance + + def save(self, context: SaveContext | None = None) -> dict[str, Any]: + """Save the FailureChunk instance to a dictionary. + Args: + context (Optional[SaveContext]): Optional context with pre/post processing callbacks. + Returns: + dict[str, Any]: The dictionary representation of this instance. + + """ + obj = self + if context is not None: + obj = context.process_object(obj) + + # Start with parent class properties + result = super().save(context) + + if obj.kind is not None: + result["kind"] = obj.kind + if obj.failure is not None: + result["failure"] = obj.failure.save(context) + return result + + def to_yaml(self, context: SaveContext | None = None) -> str: + """Convert the FailureChunk instance to a YAML string. + Args: + context (Optional[SaveContext]): Optional context with pre/post processing callbacks. + Returns: + str: The YAML string representation of this instance. + + """ + if context is None: + context = SaveContext() + return context.to_yaml(self.save(context)) + + def to_json(self, context: SaveContext | None = None, indent: int = 2) -> str: + """Convert the FailureChunk instance to a JSON string. + Args: + context (Optional[SaveContext]): Optional context with pre/post processing callbacks. + indent (int): Number of spaces for indentation. Defaults to 2. + Returns: + str: The JSON string representation of this instance. + + """ + if context is None: + context = SaveContext() + return context.to_json(self.save(context), indent) diff --git a/runtime/python/prompty/prompty/model/events/_StreamFailure.py b/runtime/python/prompty/prompty/model/events/_StreamFailure.py new file mode 100644 index 000000000..4dd879c40 --- /dev/null +++ b/runtime/python/prompty/prompty/model/events/_StreamFailure.py @@ -0,0 +1,107 @@ +# +########################################## +# WARNING: This is an auto-generated file. +# DO NOT EDIT THIS FILE DIRECTLY +# ANY EDITS WILL BE LOST +########################################## + +from dataclasses import dataclass, field +from typing import Any, ClassVar, Literal + +from .._context import LoadContext, SaveContext + +StreamFailureOutcome = Literal["determinate", "indeterminate"] + + +@dataclass +class StreamFailure: + """A classified terminal failure from an LLM response stream. + + Attributes + ---------- + outcome : str + Whether the provider outcome is known or requires reconciliation + message : str + The human-readable failure message + """ + + _shorthand_property: ClassVar[str | None] = None + + outcome: StreamFailureOutcome = field(default="determinate") + message: str = field(default="") + + @staticmethod + def load(data: Any, context: LoadContext | None = None) -> "StreamFailure": + """Load a StreamFailure instance. + Args: + data (Any): The data to load the instance from. + context (Optional[LoadContext]): Optional context with pre/post processing callbacks. + Returns: + StreamFailure: The loaded StreamFailure instance. + + """ + + if context is not None: + data = context.process_input(data) + + if not isinstance(data, dict): + raise ValueError(f"Invalid data for StreamFailure: {data}") + + # create new instance + instance = StreamFailure() + + if data is not None and "outcome" in data: + instance.outcome = data["outcome"] + if data is not None and "message" in data: + instance.message = data["message"] + if context is not None: + instance = context.process_output(instance) + return instance + + def save(self, context: SaveContext | None = None) -> dict[str, Any]: + """Save the StreamFailure instance to a dictionary. + Args: + context (Optional[SaveContext]): Optional context with pre/post processing callbacks. + Returns: + dict[str, Any]: The dictionary representation of this instance. + + """ + obj = self + if context is not None: + obj = context.process_object(obj) + + result: dict[str, Any] = {} + + if obj.outcome is not None: + result["outcome"] = obj.outcome + if obj.message is not None: + result["message"] = obj.message + + if context is not None: + result = context.process_dict(result) + return result + + def to_yaml(self, context: SaveContext | None = None) -> str: + """Convert the StreamFailure instance to a YAML string. + Args: + context (Optional[SaveContext]): Optional context with pre/post processing callbacks. + Returns: + str: The YAML string representation of this instance. + + """ + if context is None: + context = SaveContext() + return context.to_yaml(self.save(context)) + + def to_json(self, context: SaveContext | None = None, indent: int = 2) -> str: + """Convert the StreamFailure instance to a JSON string. + Args: + context (Optional[SaveContext]): Optional context with pre/post processing callbacks. + indent (int): Number of spaces for indentation. Defaults to 2. + Returns: + str: The JSON string representation of this instance. + + """ + if context is None: + context = SaveContext() + return context.to_json(self.save(context), indent) diff --git a/runtime/python/prompty/prompty/model/events/__init__.py b/runtime/python/prompty/prompty/model/events/__init__.py index d5f56fbdf..5b585f121 100644 --- a/runtime/python/prompty/prompty/model/events/__init__.py +++ b/runtime/python/prompty/prompty/model/events/__init__.py @@ -36,12 +36,14 @@ from ._StatusEventPayload import StatusEventPayload from ._StreamChunk import ( ErrorChunk, + FailureChunk, StreamChunk, TextChunk, ThinkingChunk, ToolChunk, UsageChunk, ) +from ._StreamFailure import StreamFailure from ._ThinkingEventPayload import ThinkingEventPayload from ._TokenEventPayload import TokenEventPayload from ._ToolCallCompletePayload import ToolCallCompletePayload @@ -100,10 +102,12 @@ "SessionRef", "SessionSummary", "SessionTrace", + "StreamFailure", "StreamChunk", "TextChunk", "ThinkingChunk", "ToolChunk", "UsageChunk", "ErrorChunk", + "FailureChunk", ] diff --git a/runtime/python/prompty/tests/model/events/test_stream_failure.py b/runtime/python/prompty/tests/model/events/test_stream_failure.py new file mode 100644 index 000000000..a611f9951 --- /dev/null +++ b/runtime/python/prompty/tests/model/events/test_stream_failure.py @@ -0,0 +1,82 @@ +# +import json + +import yaml + +from prompty.model import StreamFailure + + +def test_load_json_streamfailure(): + json_data = r""" + { + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" + } + """ + data = json.loads(json_data, strict=False) + instance = StreamFailure.load(data) + assert instance is not None + assert instance.outcome == "indeterminate" + assert instance.message == "SSE stream error: connection reset" + + +def test_load_yaml_streamfailure(): + yaml_data = r""" + outcome: indeterminate + message: "SSE stream error: connection reset" + + """ + data = yaml.load(yaml_data, Loader=yaml.FullLoader) + instance = StreamFailure.load(data) + assert instance is not None + assert instance.outcome == "indeterminate" + assert instance.message == "SSE stream error: connection reset" + + +def test_roundtrip_json_streamfailure(): + """Test that load -> save -> load produces equivalent data.""" + json_data = r""" + { + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" + } + """ + original_data = json.loads(json_data, strict=False) + instance = StreamFailure.load(original_data) + saved_data = instance.save() + reloaded = StreamFailure.load(saved_data) + assert reloaded is not None + assert reloaded.outcome == "indeterminate" + assert reloaded.message == "SSE stream error: connection reset" + + +def test_to_json_streamfailure(): + """Test that to_json produces valid JSON.""" + json_data = r""" + { + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" + } + """ + data = json.loads(json_data, strict=False) + instance = StreamFailure.load(data) + json_output = instance.to_json() + assert json_output is not None + parsed = json.loads(json_output) + assert isinstance(parsed, dict) + + +def test_to_yaml_streamfailure(): + """Test that to_yaml produces valid YAML.""" + json_data = r""" + { + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" + } + """ + data = json.loads(json_data, strict=False) + instance = StreamFailure.load(data) + yaml_output = instance.to_yaml() + assert yaml_output is not None + parsed = yaml.safe_load(yaml_output) + assert isinstance(parsed, dict) diff --git a/runtime/rust/prompty/src/model/events/mod.rs b/runtime/rust/prompty/src/model/events/mod.rs index 45c16b62b..a4201e3d0 100644 --- a/runtime/rust/prompty/src/model/events/mod.rs +++ b/runtime/rust/prompty/src/model/events/mod.rs @@ -138,5 +138,8 @@ pub use session_summary::*; pub mod session_trace; pub use session_trace::*; +pub mod stream_failure; +pub use stream_failure::*; + pub mod stream_chunk; pub use stream_chunk::*; diff --git a/runtime/rust/prompty/src/model/events/stream_chunk.rs b/runtime/rust/prompty/src/model/events/stream_chunk.rs index 30213cd13..1641d8770 100644 --- a/runtime/rust/prompty/src/model/events/stream_chunk.rs +++ b/runtime/rust/prompty/src/model/events/stream_chunk.rs @@ -13,6 +13,8 @@ use super::super::context::{LoadContext, SaveContext}; use super::super::model::invocation_usage::InvocationUsage; +use super::stream_failure::StreamFailure; + use super::super::conversation::tool_call::ToolCall; /// Variant-specific data for [`StreamChunk`], discriminated by `kind`. @@ -43,6 +45,11 @@ pub enum StreamChunkKind { /// The error message message: String, }, + /// `kind` = `"failure"` + FailureChunk { + /// The classified stream failure + failure: StreamFailure, + }, } impl Default for StreamChunkKind { @@ -119,6 +126,13 @@ impl StreamChunk { .unwrap_or_default() .to_string(), }, + "failure" => StreamChunkKind::FailureChunk { + failure: value + .get("failure") + .filter(|v| v.is_object() || v.is_array() || v.is_string()) + .map(|v| StreamFailure::load_from_value(v, ctx)) + .unwrap_or_default(), + }, _ => StreamChunkKind::default(), }; Self { kind: kind } @@ -132,6 +146,7 @@ impl StreamChunk { StreamChunkKind::ToolChunk { .. } => "tool", StreamChunkKind::UsageChunk { .. } => "usage", StreamChunkKind::ErrorChunk { .. } => "error", + StreamChunkKind::FailureChunk { .. } => "failure", } } @@ -184,6 +199,12 @@ impl StreamChunk { ); } } + StreamChunkKind::FailureChunk { failure, .. } => { + let nested = failure.to_value(ctx); + if !nested.is_null() { + result.insert("failure".to_string(), nested); + } + } } ctx.process_dict(serde_json::Value::Object(result)) } diff --git a/runtime/rust/prompty/src/model/events/stream_failure.rs b/runtime/rust/prompty/src/model/events/stream_failure.rs new file mode 100644 index 000000000..f84e24913 --- /dev/null +++ b/runtime/rust/prompty/src/model/events/stream_failure.rs @@ -0,0 +1,167 @@ +// +// Code generated by Typra emitter; DO NOT EDIT. + +#![allow( + unused_imports, + dead_code, + non_camel_case_types, + unused_variables, + clippy::all +)] + +use super::super::context::{LoadContext, SaveContext}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum StreamFailureOutcome { + Determinate, + Indeterminate, +} + +impl Default for StreamFailureOutcome { + fn default() -> Self { + Self::Determinate + } +} + +impl std::fmt::Display for StreamFailureOutcome { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Determinate => write!(f, "determinate"), + Self::Indeterminate => write!(f, "indeterminate"), + } + } +} + +impl StreamFailureOutcome { + pub fn from_str_opt(s: &str) -> Option { + match s { + "determinate" => Some(Self::Determinate), + "indeterminate" => Some(Self::Indeterminate), + _ => None, + } + } + + pub fn from_str_ignore_case_opt(s: &str) -> Option { + if s.eq_ignore_ascii_case("determinate") { + return Some(Self::Determinate); + } + if s.eq_ignore_ascii_case("indeterminate") { + return Some(Self::Indeterminate); + } + None + } + + pub fn as_str(&self) -> &str { + match self { + Self::Determinate => "determinate", + Self::Indeterminate => "indeterminate", + } + } +} + +impl serde::Serialize for StreamFailureOutcome { + fn serialize(&self, serializer: S) -> Result { + serializer.serialize_str(self.as_str()) + } +} + +impl<'de> serde::Deserialize<'de> for StreamFailureOutcome { + fn deserialize>(deserializer: D) -> Result { + let s = ::deserialize(deserializer)?; + Self::from_str_opt(&s).ok_or_else(|| { + serde::de::Error::custom(format!("invalid StreamFailureOutcome value: {}", s)) + }) + } +} + +/// A classified terminal failure from an LLM response stream. +#[derive(Debug, Clone, Default, PartialEq)] +pub struct StreamFailure { + /// Whether the provider outcome is known or requires reconciliation + pub outcome: StreamFailureOutcome, + /// The human-readable failure message + pub message: String, +} + +impl StreamFailure { + /// Create a new StreamFailure with default values. + pub fn new() -> Self { + Self::default() + } + + /// Load StreamFailure from a JSON string. + pub fn from_json(json: &str, ctx: &LoadContext) -> Result { + let value: serde_json::Value = serde_json::from_str(json)?; + Ok(Self::load_from_value(&value, ctx)) + } + + /// Load StreamFailure from a YAML string. + pub fn from_yaml(yaml: &str, ctx: &LoadContext) -> Result { + let value: serde_json::Value = serde_yaml::from_str(yaml)?; + Ok(Self::load_from_value(&value, ctx)) + } + + /// Load StreamFailure from a `serde_json::Value`. + /// + /// Calls `ctx.process_input` before field extraction. + pub fn load_from_value(value: &serde_json::Value, ctx: &LoadContext) -> Self { + let value = ctx.process_input(value.clone()); + Self { + outcome: value + .get("outcome") + .and_then(|v| v.as_str()) + .and_then(|s| StreamFailureOutcome::from_str_opt(s)) + .unwrap_or(StreamFailureOutcome::Determinate), + message: value + .get("message") + .and_then(|v| v.as_str()) + .unwrap_or_default() + .to_string(), + } + } + + /// Serialize StreamFailure to a `serde_json::Value`. + /// + /// Calls `ctx.process_dict` after serialization. + pub fn to_value(&self, ctx: &SaveContext) -> serde_json::Value { + let mut result = serde_json::Map::new(); + // Write base fields + result.insert( + "outcome".to_string(), + serde_json::Value::String(self.outcome.to_string()), + ); + if !self.message.is_empty() { + result.insert( + "message".to_string(), + serde_json::Value::String(self.message.clone()), + ); + } + ctx.process_dict(serde_json::Value::Object(result)) + } + + /// Serialize StreamFailure to a JSON string. + pub fn to_json(&self, ctx: &SaveContext) -> Result { + serde_json::to_string_pretty(&self.to_value(ctx)) + } + + /// Serialize StreamFailure to a YAML string. + pub fn to_yaml(&self, ctx: &SaveContext) -> Result { + serde_yaml::to_string(&self.to_value(ctx)) + } +} + +// Serde for `StreamFailure` delegates to the canonical to_value/load_from_value +// logic so its serde wire form always equals the canonical to_value/load_from_value form. Uses a default (no-op) context — no ${env:}/${file:} +// resolution here — leaving the context-aware LoadContext/SaveContext API intact. +impl serde::Serialize for StreamFailure { + fn serialize(&self, serializer: S) -> Result { + serde::Serialize::serialize(&self.to_value(&SaveContext::default()), serializer) + } +} + +impl<'de> serde::Deserialize<'de> for StreamFailure { + fn deserialize>(deserializer: D) -> Result { + let value = ::deserialize(deserializer)?; + Ok(Self::load_from_value(&value, &LoadContext::default())) + } +} diff --git a/runtime/rust/prompty/tests/model/events/mod.rs b/runtime/rust/prompty/tests/model/events/mod.rs index 24bf6570f..c6513fd57 100644 --- a/runtime/rust/prompty/tests/model/events/mod.rs +++ b/runtime/rust/prompty/tests/model/events/mod.rs @@ -40,6 +40,7 @@ mod session_trace_test; mod session_warning_payload_test; mod status_event_payload_test; mod stream_chunk_test; +mod stream_failure_test; mod thinking_event_payload_test; mod token_event_payload_test; mod tool_call_complete_payload_test; diff --git a/runtime/rust/prompty/tests/model/events/stream_failure_test.rs b/runtime/rust/prompty/tests/model/events/stream_failure_test.rs new file mode 100644 index 000000000..c8d9351b5 --- /dev/null +++ b/runtime/rust/prompty/tests/model/events/stream_failure_test.rs @@ -0,0 +1,105 @@ +// +// Code generated by Typra emitter; DO NOT EDIT. + +#![allow( + unused_imports, + dead_code, + non_camel_case_types, + unused_variables, + clippy::all +)] + +use prompty::model::StreamFailure; +use prompty::model::StreamFailureOutcome; +use prompty::model::context::{LoadContext, SaveContext}; + +#[test] +fn test_stream_failure_load_json() { + let json = r####" +{ + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" +} +"####; + let ctx = LoadContext::default(); + let result = StreamFailure::from_json(json, &ctx); + assert!( + result.is_ok(), + "Failed to load from JSON: {:?}", + result.err() + ); + let instance = result.unwrap(); + assert_eq!(instance.outcome, StreamFailureOutcome::Indeterminate); + assert_eq!(instance.message, "SSE stream error: connection reset"); +} + +#[test] +fn test_stream_failure_load_yaml() { + let yaml = r####" +outcome: indeterminate +message: "SSE stream error: connection reset" + +"####; + let ctx = LoadContext::default(); + let result = StreamFailure::from_yaml(yaml, &ctx); + assert!( + result.is_ok(), + "Failed to load from YAML: {:?}", + result.err() + ); + let instance = result.unwrap(); + assert_eq!(instance.outcome, StreamFailureOutcome::Indeterminate); + assert_eq!(instance.message, "SSE stream error: connection reset"); +} + +#[test] +fn test_stream_failure_roundtrip() { + let json = r####" +{ + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" +} +"####; + let load_ctx = LoadContext::default(); + let result = StreamFailure::from_json(json, &load_ctx); + assert!(result.is_ok(), "Failed to load: {:?}", result.err()); + let instance = result.unwrap(); + let save_ctx = SaveContext::default(); + let json_output = instance.to_json(&save_ctx); + assert!( + json_output.is_ok(), + "Failed to serialize to JSON: {:?}", + json_output.err() + ); +} + +#[test] +fn test_stream_failure_serde_roundtrip() { + let json = r####" +{ + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" +} +"####; + let instance: StreamFailure = + serde_json::from_str(json).expect("serde should deserialize canonical JSON"); + let value = serde_json::to_value(&instance).expect("serde should serialize"); + let canonical: serde_json::Value = serde_json::from_str(json).expect("canonical json parses"); + assert_eq!( + value, + instance.to_value(&SaveContext::default()), + "serde serialize must equal canonical to_value" + ); + assert_eq!( + instance, + StreamFailure::load_from_value(&canonical, &LoadContext::default()), + "serde deserialize must equal canonical load_from_value" + ); + assert_eq!( + value, canonical, + "serde must serialize to byte-identical canonical wire (empty-omission preserved; no plain-derive divergence)" + ); + let reparsed: StreamFailure = + serde_json::from_value(value).expect("serde should re-deserialize"); + assert_eq!(instance, reparsed, "serde round-trip must be stable"); +} diff --git a/runtime/typescript/packages/core/src/model/events/index.ts b/runtime/typescript/packages/core/src/model/events/index.ts index ff991d35a..297037c9a 100644 --- a/runtime/typescript/packages/core/src/model/events/index.ts +++ b/runtime/typescript/packages/core/src/model/events/index.ts @@ -45,6 +45,7 @@ export { SessionFileRef } from "./session-file-ref"; export { SessionRef } from "./session-ref"; export { SessionSummary } from "./session-summary"; export { SessionTrace } from "./session-trace"; +export { StreamFailure } from "./stream-failure"; export { StreamChunk, TextChunk, @@ -52,4 +53,5 @@ export { ToolChunk, UsageChunk, ErrorChunk, + FailureChunk, } from "./stream-chunk"; diff --git a/runtime/typescript/packages/core/src/model/events/stream-chunk.ts b/runtime/typescript/packages/core/src/model/events/stream-chunk.ts index 48feda688..319b3f25c 100644 --- a/runtime/typescript/packages/core/src/model/events/stream-chunk.ts +++ b/runtime/typescript/packages/core/src/model/events/stream-chunk.ts @@ -4,6 +4,7 @@ import { LoadContext, SaveContext } from "../context"; import { InvocationUsage } from "../model/invocation-usage"; +import { StreamFailure } from "./stream-failure"; import { ToolCall } from "../conversation/tool-call"; export abstract class StreamChunk { @@ -56,6 +57,8 @@ export abstract class StreamChunk { return UsageChunk.load(data, context); case "error": return ErrorChunk.load(data, context); + case "failure": + return FailureChunk.load(data, context); default: throw new Error( `Unknown StreamChunk discriminator value: ${discriminator}`, @@ -529,3 +532,91 @@ export class ErrorChunk extends StreamChunk { //#endregion } + +export class FailureChunk extends StreamChunk { + static readonly shorthandProperty: string | undefined = undefined; + + kind: string = "failure"; + failure!: StreamFailure; + + constructor(init?: Partial) { + super(init); + this.kind = init?.kind ?? "failure"; + if (init?.failure !== undefined) { + this.failure = init.failure; + } + } + + //#region Load Methods + + static load( + data: Record, + context?: LoadContext, + ): FailureChunk { + if (context) { + data = context.processInput(data) as Record; + } + + const instance = new FailureChunk(); + + if (data["kind"] !== undefined && data["kind"] !== null) { + instance.kind = String(data["kind"]); + } + if (data["failure"] !== undefined && data["failure"] !== null) { + instance.failure = StreamFailure.load( + data["failure"] as Record, + context, + ); + } + + if (context) { + return context.processOutput(instance) as FailureChunk; + } + return instance; + } + + //#endregion + + //#region Save Methods + + save(context?: SaveContext): Record { + let obj: this = this; + if (context) { + obj = context.processObject(obj) as this; + } + + // Start with parent class properties + const result = super.save(context); + + if (obj.kind !== undefined && obj.kind !== null) { + result["kind"] = obj.kind; + } + if (obj.failure !== undefined && obj.failure !== null) { + result["failure"] = obj.failure.save(context); + } + return result; + } + + toYaml(context?: SaveContext): string { + context = context ?? new SaveContext(); + return context.toYaml(this.save(context)); + } + + toJson(context?: SaveContext, indent: number = 2): string { + context = context ?? new SaveContext(); + return context.toJson(this.save(context), indent); + } + + static fromJson(json: string, context?: LoadContext): FailureChunk { + const data = JSON.parse(json); + return FailureChunk.load(data as Record, context); + } + + static fromYaml(yaml: string, context?: LoadContext): FailureChunk { + const { parse } = require("yaml"); + const data = parse(yaml); + return FailureChunk.load(data as Record, context); + } + + //#endregion +} diff --git a/runtime/typescript/packages/core/src/model/events/stream-failure.ts b/runtime/typescript/packages/core/src/model/events/stream-failure.ts new file mode 100644 index 000000000..5827a3f0d --- /dev/null +++ b/runtime/typescript/packages/core/src/model/events/stream-failure.ts @@ -0,0 +1,92 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// WARNING: This is an auto-generated file. DO NOT EDIT THIS FILE DIRECTLY. + +import { LoadContext, SaveContext } from "../context"; + +export type StreamFailureOutcome = "determinate" | "indeterminate"; + +export class StreamFailure { + static readonly shorthandProperty: string | undefined = undefined; + + outcome: StreamFailureOutcome = "determinate"; + message: string = ""; + + constructor(init?: Partial) { + this.outcome = init?.outcome ?? "determinate"; + this.message = init?.message ?? ""; + } + + //#region Load Methods + + static load( + data: Record, + context?: LoadContext, + ): StreamFailure { + if (context) { + data = context.processInput(data) as Record; + } + + const instance = new StreamFailure(); + + if (data["outcome"] !== undefined && data["outcome"] !== null) { + instance.outcome = String(data["outcome"]) as StreamFailureOutcome; + } + if (data["message"] !== undefined && data["message"] !== null) { + instance.message = String(data["message"]); + } + + if (context) { + return context.processOutput(instance) as StreamFailure; + } + return instance; + } + + //#endregion + + //#region Save Methods + + save(context?: SaveContext): Record { + let obj: this = this; + if (context) { + obj = context.processObject(obj) as this; + } + + const result: Record = {}; + + if (obj.outcome !== undefined && obj.outcome !== null) { + result["outcome"] = obj.outcome; + } + if (obj.message !== undefined && obj.message !== null) { + result["message"] = obj.message; + } + + if (context) { + return context.processDict(result); + } + return result; + } + + toYaml(context?: SaveContext): string { + context = context ?? new SaveContext(); + return context.toYaml(this.save(context)); + } + + toJson(context?: SaveContext, indent: number = 2): string { + context = context ?? new SaveContext(); + return context.toJson(this.save(context), indent); + } + + static fromJson(json: string, context?: LoadContext): StreamFailure { + const data = JSON.parse(json); + return StreamFailure.load(data as Record, context); + } + + static fromYaml(yaml: string, context?: LoadContext): StreamFailure { + const { parse } = require("yaml"); + const data = parse(yaml); + return StreamFailure.load(data as Record, context); + } + + //#endregion +} diff --git a/runtime/typescript/packages/core/src/model/index.ts b/runtime/typescript/packages/core/src/model/index.ts index 90a5b1a69..6698a16af 100644 --- a/runtime/typescript/packages/core/src/model/index.ts +++ b/runtime/typescript/packages/core/src/model/index.ts @@ -86,6 +86,7 @@ export { SessionFileRef } from "./events/session-file-ref"; export { SessionRef } from "./events/session-ref"; export { SessionSummary } from "./events/session-summary"; export { SessionTrace } from "./events/session-trace"; +export { StreamFailure } from "./events/stream-failure"; export { StreamChunk, TextChunk, @@ -93,6 +94,7 @@ export { ToolChunk, UsageChunk, ErrorChunk, + FailureChunk, } from "./events/stream-chunk"; export { MemoryEntry } from "./memory/memory-entry"; diff --git a/runtime/typescript/packages/core/tests/model/events/failure-chunk.test.ts b/runtime/typescript/packages/core/tests/model/events/failure-chunk.test.ts new file mode 100644 index 000000000..d55be9fcb --- /dev/null +++ b/runtime/typescript/packages/core/tests/model/events/failure-chunk.test.ts @@ -0,0 +1,34 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// WARNING: This is an auto-generated file. DO NOT EDIT THIS FILE DIRECTLY. + +import { FailureChunk } from "../../../src/model/index"; + +describe("FailureChunk", () => { + describe("construction", () => { + it("should create a new instance with defaults", () => { + const instance = new FailureChunk(); + expect(instance).toBeDefined(); + }); + + it("should create a new instance with partial initialization", () => { + const instance = new FailureChunk({}); + expect(instance).toBeDefined(); + }); + }); + + describe("load and save", () => { + it("should load from dictionary", () => { + const data: Record = {}; + const instance = FailureChunk.load(data); + expect(instance).toBeDefined(); + }); + + it("should save to dictionary", () => { + const instance = new FailureChunk(); + const data = instance.save(); + expect(data).toBeDefined(); + expect(typeof data).toBe("object"); + }); + }); +}); diff --git a/runtime/typescript/packages/core/tests/model/events/stream-failure.test.ts b/runtime/typescript/packages/core/tests/model/events/stream-failure.test.ts new file mode 100644 index 000000000..84021567e --- /dev/null +++ b/runtime/typescript/packages/core/tests/model/events/stream-failure.test.ts @@ -0,0 +1,72 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// WARNING: This is an auto-generated file. DO NOT EDIT THIS FILE DIRECTLY. + +import { StreamFailure } from "../../../src/model/index"; + +describe("StreamFailure", () => { + describe("construction", () => { + it("should create a new instance with defaults", () => { + const instance = new StreamFailure(); + expect(instance).toBeDefined(); + }); + + it("should create a new instance with partial initialization", () => { + const instance = new StreamFailure({}); + expect(instance).toBeDefined(); + }); + }); + + describe("JSON serialization", () => { + it("should load from JSON - example 1", () => { + const json = `{\n "outcome": "indeterminate",\n "message": "SSE stream error: connection reset"\n}`; + const instance = StreamFailure.fromJson(json); + expect(instance).toBeDefined(); + expect(instance.outcome).toEqual("indeterminate"); + expect(instance.message).toEqual("SSE stream error: connection reset"); + }); + + it("should round-trip JSON - example 1", () => { + const json = `{\n "outcome": "indeterminate",\n "message": "SSE stream error: connection reset"\n}`; + const instance = StreamFailure.fromJson(json); + const output = instance.toJson(); + const reloaded = StreamFailure.fromJson(output); + expect(reloaded.outcome).toEqual(instance.outcome); + expect(reloaded.message).toEqual(instance.message); + }); + }); + + describe("YAML serialization", () => { + it("should load from YAML - example 1", () => { + const yaml = `outcome: indeterminate\nmessage: "SSE stream error: connection reset"\n`; + const instance = StreamFailure.fromYaml(yaml); + expect(instance).toBeDefined(); + expect(instance.outcome).toEqual("indeterminate"); + expect(instance.message).toEqual("SSE stream error: connection reset"); + }); + + it("should round-trip YAML - example 1", () => { + const yaml = `outcome: indeterminate\nmessage: "SSE stream error: connection reset"\n`; + const instance = StreamFailure.fromYaml(yaml); + const output = instance.toYaml(); + const reloaded = StreamFailure.fromYaml(output); + expect(reloaded.outcome).toEqual(instance.outcome); + expect(reloaded.message).toEqual(instance.message); + }); + }); + + describe("load and save", () => { + it("should load from dictionary", () => { + const data: Record = {}; + const instance = StreamFailure.load(data); + expect(instance).toBeDefined(); + }); + + it("should save to dictionary", () => { + const instance = new StreamFailure(); + const data = instance.save(); + expect(data).toBeDefined(); + expect(typeof data).toBe("object"); + }); + }); +}); diff --git a/schema/model/events/stream-chunks.tsp b/schema/model/events/stream-chunks.tsp index 9324562c9..0b6ff2a90 100644 --- a/schema/model/events/stream-chunks.tsp +++ b/schema/model/events/stream-chunks.tsp @@ -7,7 +7,31 @@ namespace Prompty; /** * The kind discriminator for stream chunks. */ -alias StreamChunkType = "text" | "thinking" | "tool" | "usage" | "error"; +alias StreamChunkType = + | "text" + | "thinking" + | "tool" + | "usage" + | "error" + | "failure"; + +/** + * Whether a stream failure has a known provider outcome. + */ +alias StreamFailureOutcome = "determinate" | "indeterminate"; + +/** + * A classified terminal failure from an LLM response stream. + */ +model StreamFailure { + @doc("Whether the provider outcome is known or requires reconciliation") + @sample(#{ outcome: "indeterminate" }) + outcome: StreamFailureOutcome; + + @doc("The human-readable failure message") + @sample(#{ message: "SSE stream error: connection reset" }) + message: string; +} /** * A chunk of data from a streaming LLM response. Stream chunks are @@ -84,3 +108,14 @@ model ErrorChunk extends StreamChunk { @sample(#{ message: "Rate limit exceeded" }) message: string; } + +/** + * A classified failure chunk from the LLM response stream. + */ +model FailureChunk extends StreamChunk { + @doc("The kind identifier for classified failure chunks") + kind: "failure"; + + @doc("The classified stream failure") + failure: StreamFailure; +} diff --git a/schema/tsp-output/.typra-generated/export-surfaces.json b/schema/tsp-output/.typra-generated/export-surfaces.json index 45c400eb4..92306ab0b 100644 --- a/schema/tsp-output/.typra-generated/export-surfaces.json +++ b/schema/tsp-output/.typra-generated/export-surfaces.json @@ -73,6 +73,7 @@ "EventJournalWriter", "EventSink", "Executor", + "FailureChunk", "FileNotFoundError", "FilePart", "FinalOutputPolicyRequest", @@ -152,6 +153,7 @@ "SessionWarningPayload", "StatusEventPayload", "StreamChunk", + "StreamFailure", "StreamOptions", "SubscriptionInfo", "Template", @@ -445,6 +447,13 @@ "source": "events/ErrorEventPayload.cs", "protocol": false }, + { + "name": "FailureChunk", + "kind": "value", + "group": "events", + "source": "events/StreamChunk.cs", + "protocol": false + }, { "name": "HarnessContext", "kind": "value", @@ -620,6 +629,13 @@ "source": "events/StreamChunk.cs", "protocol": false }, + { + "name": "StreamFailure", + "kind": "value", + "group": "events", + "source": "events/StreamFailure.cs", + "protocol": false + }, { "name": "TextChunk", "kind": "value", @@ -1377,6 +1393,7 @@ "DoneEventPayload", "ErrorChunk", "ErrorEventPayload", + "FailureChunk", "HarnessContext", "HookEndPayload", "HookStartPayload", @@ -1402,6 +1419,7 @@ "SessionWarningPayload", "StatusEventPayload", "StreamChunk", + "StreamFailure", "TextChunk", "ThinkingChunk", "ThinkingEventPayload", @@ -1452,6 +1470,7 @@ "SessionWarningPayload.cs", "StatusEventPayload.cs", "StreamChunk.cs", + "StreamFailure.cs", "ThinkingEventPayload.cs", "TokenEventPayload.cs", "ToolCallCompletePayload.cs", @@ -1989,6 +2008,7 @@ "events/SessionWarningPayload.cs", "events/StatusEventPayload.cs", "events/StreamChunk.cs", + "events/StreamFailure.cs", "events/ThinkingEventPayload.cs", "events/TokenEventPayload.cs", "events/ToolCallCompletePayload.cs", @@ -2122,6 +2142,7 @@ "EventJournalWriter", "EventSink", "Executor", + "FailureChunk", "FileNotFoundError", "FilePart", "FinalOutputPolicyRequest", @@ -2201,6 +2222,7 @@ "SessionWarningPayload", "StatusEventPayload", "StreamChunk", + "StreamFailure", "StreamOptions", "SubscriptionInfo", "Template", @@ -2494,6 +2516,13 @@ "source": "error_event_payload.go", "protocol": false }, + { + "name": "FailureChunk", + "kind": "value", + "group": "events", + "source": "stream_chunk.go", + "protocol": false + }, { "name": "HarnessContext", "kind": "value", @@ -2669,6 +2698,13 @@ "source": "stream_chunk.go", "protocol": false }, + { + "name": "StreamFailure", + "kind": "value", + "group": "events", + "source": "stream_failure.go", + "protocol": false + }, { "name": "TextChunk", "kind": "value", @@ -3426,6 +3462,7 @@ "DoneEventPayload", "ErrorChunk", "ErrorEventPayload", + "FailureChunk", "HarnessContext", "HookEndPayload", "HookStartPayload", @@ -3451,6 +3488,7 @@ "SessionWarningPayload", "StatusEventPayload", "StreamChunk", + "StreamFailure", "TextChunk", "ThinkingChunk", "ThinkingEventPayload", @@ -3501,6 +3539,7 @@ "session_warning_payload", "status_event_payload", "stream_chunk", + "stream_failure", "thinking_event_payload", "token_event_payload", "tool_call_complete_payload", @@ -4092,6 +4131,7 @@ "session_warning_payload.go", "status_event_payload.go", "stream_chunk.go", + "stream_failure.go", "stream_options.go", "subscription_info.go", "template.go", @@ -4170,6 +4210,7 @@ "EventJournalWriter", "EventSink", "Executor", + "FailureChunk", "FileNotFoundError", "FilePart", "FinalOutputPolicyRequest", @@ -4249,6 +4290,7 @@ "SessionWarningPayload", "StatusEventPayload", "StreamChunk", + "StreamFailure", "StreamOptions", "SubscriptionInfo", "Template", @@ -4542,6 +4584,13 @@ "source": "ErrorEventPayload", "protocol": false }, + { + "name": "FailureChunk", + "kind": "value", + "group": "events", + "source": "StreamChunk", + "protocol": false + }, { "name": "HarnessContext", "kind": "value", @@ -4717,6 +4766,13 @@ "source": "StreamChunk", "protocol": false }, + { + "name": "StreamFailure", + "kind": "value", + "group": "events", + "source": "StreamFailure", + "protocol": false + }, { "name": "TextChunk", "kind": "value", @@ -5474,6 +5530,7 @@ "DoneEventPayload", "ErrorChunk", "ErrorEventPayload", + "FailureChunk", "HarnessContext", "HookEndPayload", "HookStartPayload", @@ -5499,6 +5556,7 @@ "SessionWarningPayload", "StatusEventPayload", "StreamChunk", + "StreamFailure", "TextChunk", "ThinkingChunk", "ThinkingEventPayload", @@ -5549,6 +5607,7 @@ "session_warning_payload", "status_event_payload", "stream_chunk", + "stream_failure", "thinking_event_payload", "token_event_payload", "tool_call_complete_payload", @@ -6140,6 +6199,7 @@ "SessionWarningPayload", "StatusEventPayload", "StreamChunk", + "StreamFailure", "StreamOptions", "SubscriptionInfo", "Template", @@ -6219,6 +6279,7 @@ "EventJournalWriter", "EventSink", "Executor", + "FailureChunk", "FileNotFoundError", "FilePart", "FinalOutputPolicyRequest", @@ -6298,6 +6359,7 @@ "SessionWarningPayload", "StatusEventPayload", "StreamChunk", + "StreamFailure", "StreamOptions", "SubscriptionInfo", "Template", @@ -6591,6 +6653,13 @@ "source": ".events", "protocol": false }, + { + "name": "FailureChunk", + "kind": "value", + "group": "events", + "source": ".events", + "protocol": false + }, { "name": "HarnessContext", "kind": "value", @@ -6766,6 +6835,13 @@ "source": ".events", "protocol": false }, + { + "name": "StreamFailure", + "kind": "value", + "group": "events", + "source": ".events", + "protocol": false + }, { "name": "TextChunk", "kind": "value", @@ -7523,6 +7599,7 @@ "DoneEventPayload", "ErrorChunk", "ErrorEventPayload", + "FailureChunk", "HarnessContext", "HookEndPayload", "HookStartPayload", @@ -7548,6 +7625,7 @@ "SessionWarningPayload", "StatusEventPayload", "StreamChunk", + "StreamFailure", "TextChunk", "ThinkingChunk", "ThinkingEventPayload", @@ -7598,6 +7676,7 @@ "_SessionWarningPayload", "_StatusEventPayload", "_StreamChunk", + "_StreamFailure", "_ThinkingEventPayload", "_TokenEventPayload", "_ToolCallCompletePayload", @@ -8146,6 +8225,7 @@ "EventJournalWriter", "EventSink", "Executor", + "FailureChunk", "FileNotFoundError", "FilePart", "FinalOutputPolicyRequest", @@ -8225,6 +8305,7 @@ "SessionWarningPayload", "StatusEventPayload", "StreamChunk", + "StreamFailure", "StreamOptions", "SubscriptionInfo", "Template", @@ -8518,6 +8599,13 @@ "source": "events::error_event_payload", "protocol": false }, + { + "name": "FailureChunk", + "kind": "value", + "group": "events", + "source": "events::stream_chunk", + "protocol": false + }, { "name": "HarnessContext", "kind": "value", @@ -8693,6 +8781,13 @@ "source": "events::stream_chunk", "protocol": false }, + { + "name": "StreamFailure", + "kind": "value", + "group": "events", + "source": "events::stream_failure", + "protocol": false + }, { "name": "TextChunk", "kind": "value", @@ -9450,6 +9545,7 @@ "DoneEventPayload", "ErrorChunk", "ErrorEventPayload", + "FailureChunk", "HarnessContext", "HookEndPayload", "HookStartPayload", @@ -9475,6 +9571,7 @@ "SessionWarningPayload", "StatusEventPayload", "StreamChunk", + "StreamFailure", "TextChunk", "ThinkingChunk", "ThinkingEventPayload", @@ -9525,6 +9622,7 @@ "session_warning_payload", "status_event_payload", "stream_chunk", + "stream_failure", "thinking_event_payload", "token_event_payload", "tool_call_complete_payload", @@ -10075,6 +10173,7 @@ "EventJournalWriter", "EventSink", "Executor", + "FailureChunk", "FileNotFoundError", "FilePart", "FinalOutputPolicyRequest", @@ -10154,6 +10253,7 @@ "SessionWarningPayload", "StatusEventPayload", "StreamChunk", + "StreamFailure", "StreamOptions", "SubscriptionInfo", "Template", @@ -10447,6 +10547,13 @@ "source": "./events/error-event-payload", "protocol": false }, + { + "name": "FailureChunk", + "kind": "value", + "group": "events", + "source": "./events/stream-chunk", + "protocol": false + }, { "name": "HarnessContext", "kind": "value", @@ -10622,6 +10729,13 @@ "source": "./events/stream-chunk", "protocol": false }, + { + "name": "StreamFailure", + "kind": "value", + "group": "events", + "source": "./events/stream-failure", + "protocol": false + }, { "name": "TextChunk", "kind": "value", @@ -11379,6 +11493,7 @@ "DoneEventPayload", "ErrorChunk", "ErrorEventPayload", + "FailureChunk", "HarnessContext", "HookEndPayload", "HookStartPayload", @@ -11404,6 +11519,7 @@ "SessionWarningPayload", "StatusEventPayload", "StreamChunk", + "StreamFailure", "TextChunk", "ThinkingChunk", "ThinkingEventPayload", @@ -11454,6 +11570,7 @@ "session-warning-payload", "status-event-payload", "stream-chunk", + "stream-failure", "thinking-event-payload", "token-event-payload", "tool-call-complete-payload", @@ -11991,6 +12108,7 @@ "./events/session-warning-payload", "./events/status-event-payload", "./events/stream-chunk", + "./events/stream-failure", "./events/thinking-event-payload", "./events/token-event-payload", "./events/tool-call-complete-payload", diff --git a/schema/tsp-output/.typra-generated/manifest.json b/schema/tsp-output/.typra-generated/manifest.json index 4581f6480..d11643e00 100644 --- a/schema/tsp-output/.typra-generated/manifest.json +++ b/schema/tsp-output/.typra-generated/manifest.json @@ -183,6 +183,11 @@ "path": "../runtime/csharp/Prompty.Core.Tests/Model/events/ErrorEventPayloadConversionTests.cs", "marker": true }, + { + "outputRoot": "../runtime/csharp/Prompty.Core.Tests/Model", + "path": "../runtime/csharp/Prompty.Core.Tests/Model/events/FailureChunkConversionTests.cs", + "marker": true + }, { "outputRoot": "../runtime/csharp/Prompty.Core.Tests/Model", "path": "../runtime/csharp/Prompty.Core.Tests/Model/events/HarnessContextConversionTests.cs", @@ -308,6 +313,11 @@ "path": "../runtime/csharp/Prompty.Core.Tests/Model/events/StreamChunkConversionTests.cs", "marker": true }, + { + "outputRoot": "../runtime/csharp/Prompty.Core.Tests/Model", + "path": "../runtime/csharp/Prompty.Core.Tests/Model/events/StreamFailureConversionTests.cs", + "marker": true + }, { "outputRoot": "../runtime/csharp/Prompty.Core.Tests/Model", "path": "../runtime/csharp/Prompty.Core.Tests/Model/events/TextChunkConversionTests.cs", @@ -938,6 +948,11 @@ "path": "../runtime/csharp/Prompty.Core/Model/events/ErrorEventPayload.cs", "marker": true }, + { + "outputRoot": "../runtime/csharp/Prompty.Core/Model", + "path": "../runtime/csharp/Prompty.Core/Model/events/FailureChunk.cs", + "marker": true + }, { "outputRoot": "../runtime/csharp/Prompty.Core/Model", "path": "../runtime/csharp/Prompty.Core/Model/events/HarnessContext.cs", @@ -1093,6 +1108,16 @@ "path": "../runtime/csharp/Prompty.Core/Model/events/StreamChunk.cs", "marker": true }, + { + "outputRoot": "../runtime/csharp/Prompty.Core/Model", + "path": "../runtime/csharp/Prompty.Core/Model/events/StreamFailure.cs", + "marker": true + }, + { + "outputRoot": "../runtime/csharp/Prompty.Core/Model", + "path": "../runtime/csharp/Prompty.Core/Model/events/StreamFailureOutcome.cs", + "marker": true + }, { "outputRoot": "../runtime/csharp/Prompty.Core/Model", "path": "../runtime/csharp/Prompty.Core/Model/events/TextChunk.cs", @@ -1988,6 +2013,11 @@ "path": "../runtime/go/prompty/model/executor.go", "marker": true }, + { + "outputRoot": "../runtime/go/prompty/model", + "path": "../runtime/go/prompty/model/failure_chunk_test.go", + "marker": true + }, { "outputRoot": "../runtime/go/prompty/model", "path": "../runtime/go/prompty/model/file_not_found_error_test.go", @@ -2693,6 +2723,16 @@ "path": "../runtime/go/prompty/model/stream_chunk.go", "marker": true }, + { + "outputRoot": "../runtime/go/prompty/model", + "path": "../runtime/go/prompty/model/stream_failure_test.go", + "marker": true + }, + { + "outputRoot": "../runtime/go/prompty/model", + "path": "../runtime/go/prompty/model/stream_failure.go", + "marker": true + }, { "outputRoot": "../runtime/go/prompty/model", "path": "../runtime/go/prompty/model/stream_options_test.go", @@ -3323,6 +3363,11 @@ "path": "../runtime/python/prompty/prompty/model/events/_StreamChunk.py", "marker": true }, + { + "outputRoot": "../runtime/python/prompty/prompty/model", + "path": "../runtime/python/prompty/prompty/model/events/_StreamFailure.py", + "marker": true + }, { "outputRoot": "../runtime/python/prompty/prompty/model", "path": "../runtime/python/prompty/prompty/model/events/_ThinkingEventPayload.py", @@ -4078,6 +4123,11 @@ "path": "../runtime/python/prompty/tests/model/events/test_status_event_payload.py", "marker": true }, + { + "outputRoot": "../runtime/python/prompty/tests/model", + "path": "../runtime/python/prompty/tests/model/events/test_stream_failure.py", + "marker": true + }, { "outputRoot": "../runtime/python/prompty/tests/model", "path": "../runtime/python/prompty/tests/model/events/test_text_chunk.py", @@ -4673,6 +4723,11 @@ "path": "../runtime/rust/prompty/src/model/events/stream_chunk.rs", "marker": true }, + { + "outputRoot": "../runtime/rust/prompty/src/model", + "path": "../runtime/rust/prompty/src/model/events/stream_failure.rs", + "marker": true + }, { "outputRoot": "../runtime/rust/prompty/src/model", "path": "../runtime/rust/prompty/src/model/events/thinking_event_payload.rs", @@ -5413,6 +5468,11 @@ "path": "../runtime/rust/prompty/tests/model/events/stream_chunk_test.rs", "marker": true }, + { + "outputRoot": "../runtime/rust/prompty/tests/model", + "path": "../runtime/rust/prompty/tests/model/events/stream_failure_test.rs", + "marker": true + }, { "outputRoot": "../runtime/rust/prompty/tests/model", "path": "../runtime/rust/prompty/tests/model/events/thinking_event_payload_test.rs", @@ -6113,6 +6173,11 @@ "path": "../runtime/typescript/packages/core/src/model/events/stream-chunk.ts", "marker": true }, + { + "outputRoot": "../runtime/typescript/packages/core/src/model", + "path": "../runtime/typescript/packages/core/src/model/events/stream-failure.ts", + "marker": true + }, { "outputRoot": "../runtime/typescript/packages/core/src/model", "path": "../runtime/typescript/packages/core/src/model/events/thinking-event-payload.ts", @@ -6773,6 +6838,11 @@ "path": "../runtime/typescript/packages/core/tests/model/events/error-event-payload.test.ts", "marker": true }, + { + "outputRoot": "../runtime/typescript/packages/core/tests/model", + "path": "../runtime/typescript/packages/core/tests/model/events/failure-chunk.test.ts", + "marker": true + }, { "outputRoot": "../runtime/typescript/packages/core/tests/model", "path": "../runtime/typescript/packages/core/tests/model/events/harness-context.test.ts", @@ -6898,6 +6968,11 @@ "path": "../runtime/typescript/packages/core/tests/model/events/stream-chunk.test.ts", "marker": true }, + { + "outputRoot": "../runtime/typescript/packages/core/tests/model", + "path": "../runtime/typescript/packages/core/tests/model/events/stream-failure.test.ts", + "marker": true + }, { "outputRoot": "../runtime/typescript/packages/core/tests/model", "path": "../runtime/typescript/packages/core/tests/model/events/text-chunk.test.ts", @@ -7523,6 +7598,11 @@ "path": "../web/src/content/docs/reference/Executor.md", "marker": true }, + { + "outputRoot": "../web/src/content/docs/reference", + "path": "../web/src/content/docs/reference/FailureChunk.md", + "marker": true + }, { "outputRoot": "../web/src/content/docs/reference", "path": "../web/src/content/docs/reference/FileNotFoundError.md", @@ -7923,6 +8003,11 @@ "path": "../web/src/content/docs/reference/StreamChunk.md", "marker": true }, + { + "outputRoot": "../web/src/content/docs/reference", + "path": "../web/src/content/docs/reference/StreamFailure.md", + "marker": true + }, { "outputRoot": "../web/src/content/docs/reference", "path": "../web/src/content/docs/reference/StreamOptions.md", diff --git a/spec/vectors/process/stream_failure_vectors.json b/spec/vectors/process/stream_failure_vectors.json new file mode 100644 index 000000000..b5777dad8 --- /dev/null +++ b/spec/vectors/process/stream_failure_vectors.json @@ -0,0 +1,80 @@ +[ + { + "name": "stream_refusal_is_determinate", + "description": "A model refusal is a determinate terminal failure and never commits a completion", + "input": { + "provider": "openai", + "events": [ + { + "kind": "provider", + "value": { + "choices": [ + { + "delta": { + "refusal": "I cannot help with that" + } + } + ] + } + } + ] + }, + "expected": { + "chunks": [ + { + "kind": "failure", + "failure": { + "outcome": "determinate", + "message": "Model refused: I cannot help with that" + } + } + ], + "partialText": "", + "requiresReconciliation": false, + "completionCommitted": false + } + }, + { + "name": "partial_text_then_indeterminate_failure", + "description": "A post-open transport failure preserves partial text, requires reconciliation, and never commits a completion", + "input": { + "provider": "openai", + "events": [ + { + "kind": "provider", + "value": { + "choices": [ + { + "delta": { + "content": "partial" + } + } + ] + } + }, + { + "kind": "transportError", + "message": "SSE stream error: connection reset" + } + ] + }, + "expected": { + "chunks": [ + { + "kind": "text", + "value": "partial" + }, + { + "kind": "failure", + "failure": { + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" + } + } + ], + "partialText": "partial", + "requiresReconciliation": true, + "completionCommitted": false + } + } +] diff --git a/vscode/prompty/schemas/FailureChunk.yaml b/vscode/prompty/schemas/FailureChunk.yaml new file mode 100644 index 000000000..7afd7e6a2 --- /dev/null +++ b/vscode/prompty/schemas/FailureChunk.yaml @@ -0,0 +1,17 @@ +$schema: https://json-schema.org/draft/2020-12/schema +$id: FailureChunk.yaml +type: object +properties: + kind: + type: string + const: failure + description: The kind identifier for classified failure chunks + failure: + $ref: StreamFailure.yaml + description: The classified stream failure +required: + - kind + - failure +allOf: + - $ref: StreamChunk.yaml +description: A classified failure chunk from the LLM response stream. diff --git a/vscode/prompty/schemas/StreamChunk.yaml b/vscode/prompty/schemas/StreamChunk.yaml index f88cf9675..bb9d0676c 100644 --- a/vscode/prompty/schemas/StreamChunk.yaml +++ b/vscode/prompty/schemas/StreamChunk.yaml @@ -14,6 +14,8 @@ properties: const: usage - type: string const: error + - type: string + const: failure description: The kind of stream chunk required: - kind diff --git a/vscode/prompty/schemas/StreamFailure.yaml b/vscode/prompty/schemas/StreamFailure.yaml new file mode 100644 index 000000000..4b326ac50 --- /dev/null +++ b/vscode/prompty/schemas/StreamFailure.yaml @@ -0,0 +1,18 @@ +$schema: https://json-schema.org/draft/2020-12/schema +$id: StreamFailure.yaml +type: object +properties: + outcome: + anyOf: + - type: string + const: determinate + - type: string + const: indeterminate + description: Whether the provider outcome is known or requires reconciliation + message: + type: string + description: The human-readable failure message +required: + - outcome + - message +description: A classified terminal failure from an LLM response stream. diff --git a/web/src/content/docs/reference/FailureChunk.md b/web/src/content/docs/reference/FailureChunk.md new file mode 100644 index 000000000..0f1c05004 --- /dev/null +++ b/web/src/content/docs/reference/FailureChunk.md @@ -0,0 +1,49 @@ +--- +title: "FailureChunk" +description: "Documentation for the FailureChunk type." +slug: "reference/failurechunk" +--- + + +A classified failure chunk from the LLM response stream. + +## Class Diagram + +```mermaid +--- +title: FailureChunk +config: + look: handDrawn + theme: colorful + class: + hideEmptyMembersBox: true +--- +classDiagram + class StreamChunk { + <> + +string kind + } + StreamChunk <|-- FailureChunk + class FailureChunk { + +string kind + +StreamFailure failure + } + class StreamFailure { + +string outcome + +string message + } + FailureChunk *-- StreamFailure +``` + +## Properties + +| Name | Type | Description | +| ---- | ---- | ----------- | +| kind | string | The kind identifier for classified failure chunks | +| failure | [StreamFailure](../streamfailure/) | The classified stream failure | + +## Composed Types + +The following types are composed within `FailureChunk`: + +- [StreamFailure](../streamfailure/) diff --git a/web/src/content/docs/reference/StreamChunk.md b/web/src/content/docs/reference/StreamChunk.md index d866f79ad..72f3bcbbb 100644 --- a/web/src/content/docs/reference/StreamChunk.md +++ b/web/src/content/docs/reference/StreamChunk.md @@ -49,6 +49,11 @@ classDiagram +string message } StreamChunk <|-- ErrorChunk + class FailureChunk { + +string kind + +StreamFailure failure + } + StreamChunk <|-- FailureChunk ``` ## Properties @@ -66,3 +71,4 @@ The following types extend `StreamChunk`: - [ToolChunk](../toolchunk/) - [UsageChunk](../usagechunk/) - [ErrorChunk](../errorchunk/) +- [FailureChunk](../failurechunk/) diff --git a/web/src/content/docs/reference/StreamFailure.md b/web/src/content/docs/reference/StreamFailure.md new file mode 100644 index 000000000..45e925956 --- /dev/null +++ b/web/src/content/docs/reference/StreamFailure.md @@ -0,0 +1,40 @@ +--- +title: "StreamFailure" +description: "Documentation for the StreamFailure type." +slug: "reference/streamfailure" +--- + + +A classified terminal failure from an LLM response stream. + +## Class Diagram + +```mermaid +--- +title: StreamFailure +config: + look: handDrawn + theme: colorful + class: + hideEmptyMembersBox: true +--- +classDiagram + class StreamFailure { + +string outcome + +string message + } +``` + +## Yaml Example + +```yaml +outcome: indeterminate +message: "SSE stream error: connection reset" +``` + +## Properties + +| Name | Type | Description | +| ---- | ---- | ----------- | +| outcome | string | Whether the provider outcome is known or requires reconciliation | +| message | string | The human-readable failure message | From 2abeb65ad3c182e7304802daf9ec539c1d939992 Mon Sep 17 00:00:00 2001 From: Seth Juarez Date: Tue, 4 Aug 2026 00:34:22 -0700 Subject: [PATCH 02/10] feat(rust): bridge canonical stream failures Preserve the published handwritten stream API while mapping classified failures to generated models, consuming shared vectors, and enforcing reconciliation without completion commits. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- runtime/rust/prompty-openai/src/processor.rs | 22 ++- .../tests/stream_failure_vectors.rs | 83 +++++++++ .../rust/prompty/src/pipeline/live_turn.rs | 161 ++++++++++++++++-- runtime/rust/prompty/src/types.rs | 43 ++++- .../tests/stream_chunk_compatibility.rs | 32 ++++ 5 files changed, 321 insertions(+), 20 deletions(-) create mode 100644 runtime/rust/prompty-openai/tests/stream_failure_vectors.rs diff --git a/runtime/rust/prompty-openai/src/processor.rs b/runtime/rust/prompty-openai/src/processor.rs index 9b97e75bb..1f9f8a7b8 100644 --- a/runtime/rust/prompty-openai/src/processor.rs +++ b/runtime/rust/prompty-openai/src/processor.rs @@ -617,8 +617,10 @@ impl futures::Stream for OpenAIStreamProcessor { if let Some(refusal) = chunk.get("delta").and_then(Value::as_str) { if !refusal.is_empty() { this.phase = StreamPhase::Done; - return std::task::Poll::Ready(Some(StreamChunk::Error( - format!("Model refused: {refusal}"), + return std::task::Poll::Ready(Some(StreamChunk::Failure( + StreamFailure::Determinate(format!( + "Model refused: {refusal}" + )), ))); } } @@ -679,8 +681,10 @@ impl futures::Stream for OpenAIStreamProcessor { if let Some(refusal) = delta.get("refusal").and_then(Value::as_str) { if !refusal.is_empty() { this.phase = StreamPhase::Done; - return std::task::Poll::Ready(Some(StreamChunk::Error( - format!("Model refused: {refusal}"), + return std::task::Poll::Ready(Some(StreamChunk::Failure( + StreamFailure::Determinate(format!( + "Model refused: {refusal}" + )), ))); } } @@ -1292,14 +1296,14 @@ mod tests { let chunks = vec![json!({"choices": [{"delta": {"refusal": "I cannot help with that"}}]})]; let inner = futures::stream::iter(chunks); let mut stream = process_stream(inner); - let mut errors = Vec::new(); + let mut failures = Vec::new(); while let Some(chunk) = stream.next().await { - if let StreamChunk::Error(message) = chunk { - errors.push(message); + if let StreamChunk::Failure(StreamFailure::Determinate(message)) = chunk { + failures.push(message); } } - assert_eq!(errors.len(), 1); - assert!(errors[0].contains("refused")); + assert_eq!(failures.len(), 1); + assert!(failures[0].contains("refused")); } #[tokio::test] diff --git a/runtime/rust/prompty-openai/tests/stream_failure_vectors.rs b/runtime/rust/prompty-openai/tests/stream_failure_vectors.rs new file mode 100644 index 000000000..4576bafed --- /dev/null +++ b/runtime/rust/prompty-openai/tests/stream_failure_vectors.rs @@ -0,0 +1,83 @@ +use futures::StreamExt; +use prompty::types::{StreamChunk, StreamFailure}; +use serde_json::{Value, json}; + +fn load_vectors() -> Vec { + let path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("..") + .join("..") + .join("..") + .join("spec") + .join("vectors") + .join("process") + .join("stream_failure_vectors.json"); + serde_json::from_str( + &std::fs::read_to_string(&path) + .unwrap_or_else(|error| panic!("Failed to read {}: {error}", path.display())), + ) + .expect("Invalid stream failure vectors") +} + +fn provider_chunks(events: &[Value]) -> Vec { + events + .iter() + .map(|event| match event["kind"].as_str() { + Some("provider") => event["value"].clone(), + Some("transportError") => json!({ + "error": { + "type": "sse_transport_error", + "message": event["message"], + } + }), + kind => panic!("Unsupported stream vector event kind: {kind:?}"), + }) + .collect() +} + +fn chunk_to_value(chunk: StreamChunk) -> Value { + match chunk { + StreamChunk::Text(value) => json!({"kind": "text", "value": value}), + StreamChunk::Failure(failure) => json!({ + "kind": "failure", + "failure": { + "outcome": if failure.outcome_unknown() { + "indeterminate" + } else { + "determinate" + }, + "message": failure.message(), + } + }), + other => panic!("Unexpected processed stream chunk: {other:?}"), + } +} + +#[tokio::test] +async fn openai_stream_processor_matches_classified_failure_vectors() { + for vector in load_vectors() { + let input = &vector["input"]; + assert_eq!(input["provider"], "openai"); + let events = input["events"] + .as_array() + .expect("stream vector events must be an array"); + let chunks = provider_chunks(events); + let actual: Vec = + prompty_openai::processor::process_stream(futures::stream::iter(chunks)) + .map(chunk_to_value) + .collect() + .await; + + assert_eq!( + Value::Array(actual), + vector["expected"]["chunks"], + "stream failure vector '{}' did not match", + vector["name"] + ); + } +} + +#[test] +fn compatibility_failure_outcomes_match_vector_contract() { + assert!(!StreamFailure::Determinate(String::new()).outcome_unknown()); + assert!(StreamFailure::Indeterminate(String::new()).outcome_unknown()); +} diff --git a/runtime/rust/prompty/src/pipeline/live_turn.rs b/runtime/rust/prompty/src/pipeline/live_turn.rs index f2ed53174..d405319ed 100644 --- a/runtime/rust/prompty/src/pipeline/live_turn.rs +++ b/runtime/rust/prompty/src/pipeline/live_turn.rs @@ -1404,9 +1404,30 @@ mod tests { use crate::types::StreamFailure; const RESPONSES_STREAM_PROVIDER: &str = "live-responses-stream-test"; + const DETERMINATE_STREAM_PROVIDER: &str = "live-determinate-stream-test"; const INDETERMINATE_STREAM_PROVIDER: &str = "live-indeterminate-stream-test"; const POST_OPEN_INDETERMINATE_STREAM_PROVIDER: &str = "live-post-open-indeterminate-stream-test"; + + fn stream_failure_vector(name: &str) -> Value { + let path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("..") + .join("..") + .join("..") + .join("spec") + .join("vectors") + .join("process") + .join("stream_failure_vectors.json"); + let vectors: Vec = serde_json::from_str( + &std::fs::read_to_string(&path) + .unwrap_or_else(|error| panic!("Failed to read {}: {error}", path.display())), + ) + .expect("Invalid stream failure vectors"); + vectors + .into_iter() + .find(|vector| vector["name"] == name) + .unwrap_or_else(|| panic!("Missing stream failure vector '{name}'")) + } static INDETERMINATE_STREAM_OPEN_CALLS: AtomicU64 = AtomicU64::new(0); static INDETERMINATE_NON_STREAM_CALLS: AtomicU64 = AtomicU64::new(0); @@ -1866,12 +1887,38 @@ mod tests { struct ResponsesStreamProcessor; + struct DeterminateStreamExecutor; + + struct DeterminateStreamProcessor; + struct IndeterminateStreamExecutor; struct PostOpenIndeterminateStreamExecutor; struct PostOpenIndeterminateStreamProcessor; + #[async_trait] + impl Executor for DeterminateStreamExecutor { + async fn execute( + &self, + _agent: &Prompty, + _messages: &[Message], + ) -> Result { + unreachable!("the test exercises the streaming path") + } + + async fn execute_stream_with_context( + &self, + _agent: &Prompty, + _request: &ModelInvocationRequest, + _cancellation: &CancellationToken, + ) -> Result + Send>>, InvokerError> { + Ok(Box::pin(futures::stream::iter(vec![json!({ + "refusal": "I cannot help with that" + })]))) + } + } + #[async_trait] impl Executor for IndeterminateStreamExecutor { async fn execute( @@ -2023,6 +2070,22 @@ mod tests { } } + #[async_trait] + impl Processor for DeterminateStreamProcessor { + async fn process(&self, _agent: &Prompty, _response: Value) -> Result { + unreachable!("the test exercises the streaming path") + } + + fn process_stream( + &self, + _stream: Pin + Send>>, + ) -> Result + Send>>, InvokerError> { + Ok(Box::pin(futures::stream::iter(vec![StreamChunk::Failure( + StreamFailure::Determinate("Model refused: I cannot help with that".to_string()), + )]))) + } + } + fn responses_agent() -> Prompty { Prompty::load_from_value( &json!({ @@ -2137,6 +2200,8 @@ mod tests { #[tokio::test] async fn post_open_indeterminate_stream_requires_reconciliation_without_success_commit() { + let vector = stream_failure_vector("partial_text_then_indeterminate_failure"); + let expected = &vector["expected"]; registry::register_executor( POST_OPEN_INDETERMINATE_STREAM_PROVIDER, PostOpenIndeterminateStreamExecutor, @@ -2174,6 +2239,7 @@ mod tests { Some( TurnOptions::builder() .durability(durability.clone()) + .max_llm_retries(1) .on_event(Box::new(move |event| { captured_events .lock() @@ -2188,15 +2254,19 @@ mod tests { assert!(matches!(error, InvokerError::ExecuteIndeterminate { .. })); let events = events.lock().expect("event lock poisoned"); - assert!( - events - .iter() - .any(|event| { matches!(event, AgentEvent::Token(value) if value == "partial") }) - ); - assert!( - !events - .iter() - .any(|event| matches!(event, AgentEvent::Done { .. })) + assert!(events.iter().any(|event| { + matches!( + event, + AgentEvent::Token(value) + if Some(value.as_str()) == expected["partialText"].as_str() + ) + })); + let completion_committed = events + .iter() + .any(|event| matches!(event, AgentEvent::Done { .. })); + assert_eq!( + completion_committed, + expected["completionCommitted"].as_bool().unwrap() ); drop(events); let checkpoint = durability @@ -2206,11 +2276,82 @@ mod tests { .last() .cloned() .expect("indeterminate invocation must persist a reconciliation checkpoint"); - assert!(checkpoint.reconciliation_required); + assert_eq!( + checkpoint.reconciliation_required, + expected["requiresReconciliation"].as_bool().unwrap() + ); assert!(!checkpoint.final_output_ready); assert!(checkpoint.pending_output.is_none()); } + #[tokio::test] + async fn determinate_stream_failure_does_not_reconcile_or_commit_completion() { + let vector = stream_failure_vector("stream_refusal_is_determinate"); + let expected = &vector["expected"]; + registry::register_executor(DETERMINATE_STREAM_PROVIDER, DeterminateStreamExecutor); + registry::register_processor(DETERMINATE_STREAM_PROVIDER, DeterminateStreamProcessor); + let durability = Arc::new(CheckpointRecorder::default()); + let events = Arc::new(Mutex::new(Vec::new())); + let captured_events = events.clone(); + + let error = turn_with_engine_request( + &Prompty::load_from_value( + &json!({ + "kind": "prompt", + "name": "determinate-stream-failure", + "instructions": "test", + "model": { + "id": "gpt-test", + "provider": DETERMINATE_STREAM_PROVIDER, + "options": { + "additionalProperties": {"stream": true} + } + } + }), + &LoadContext::default(), + ), + TurnEngineRequest::new( + "determinate-stream-session", + "determinate-stream-turn", + vec![Message::with_text(crate::types::Role::User, "hello")], + ), + Some( + TurnOptions::builder() + .durability(durability.clone()) + .max_llm_retries(1) + .on_event(Box::new(move |event| { + captured_events + .lock() + .expect("event lock poisoned") + .push(event); + })) + .build(), + ), + ) + .await + .expect_err("determinate stream failure must fail the turn"); + + assert!(!matches!(error, InvokerError::ExecuteIndeterminate { .. })); + let completion_committed = events + .lock() + .expect("event lock poisoned") + .iter() + .any(|event| matches!(event, AgentEvent::Done { .. })); + assert_eq!( + completion_committed, + expected["completionCommitted"].as_bool().unwrap() + ); + assert_eq!( + durability + .checkpoints + .lock() + .unwrap() + .iter() + .any(|checkpoint| checkpoint.reconciliation_required), + expected["requiresReconciliation"].as_bool().unwrap() + ); + } + #[tokio::test] async fn indeterminate_stream_open_requires_reconciliation_without_fallback() { INDETERMINATE_STREAM_OPEN_CALLS.store(0, Ordering::SeqCst); diff --git a/runtime/rust/prompty/src/types.rs b/runtime/rust/prompty/src/types.rs index cc6ca8bc2..0aa39b214 100644 --- a/runtime/rust/prompty/src/types.rs +++ b/runtime/rust/prompty/src/types.rs @@ -299,7 +299,7 @@ pub enum StreamChunk { /// Transport failures after a response has opened are indeterminate: the provider /// may have accepted or completed the invocation even though the local stream /// ended before a terminal response was received. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum StreamFailure { /// The stream failed deterministically (for example, a model refusal). Determinate(String), @@ -319,6 +319,47 @@ impl StreamFailure { pub fn outcome_unknown(&self) -> bool { matches!(self, Self::Indeterminate(_)) } + + /// Convert this compatibility type to the canonical generated model. + pub fn to_model(&self) -> crate::model::StreamFailure { + self.into() + } + + /// Convert a canonical generated model into the compatibility type. + pub fn from_model(failure: crate::model::StreamFailure) -> Self { + failure.into() + } +} + +impl From<&StreamFailure> for crate::model::StreamFailure { + fn from(failure: &StreamFailure) -> Self { + let outcome = if failure.outcome_unknown() { + crate::model::StreamFailureOutcome::Indeterminate + } else { + crate::model::StreamFailureOutcome::Determinate + }; + Self { + outcome, + message: failure.message().to_string(), + } + } +} + +impl From for crate::model::StreamFailure { + fn from(failure: StreamFailure) -> Self { + (&failure).into() + } +} + +impl From for StreamFailure { + fn from(failure: crate::model::StreamFailure) -> Self { + match failure.outcome { + crate::model::StreamFailureOutcome::Determinate => Self::Determinate(failure.message), + crate::model::StreamFailureOutcome::Indeterminate => { + Self::Indeterminate(failure.message) + } + } + } } // --------------------------------------------------------------------------- diff --git a/runtime/rust/prompty/tests/stream_chunk_compatibility.rs b/runtime/rust/prompty/tests/stream_chunk_compatibility.rs index 9303e2fd7..5d202727b 100644 --- a/runtime/rust/prompty/tests/stream_chunk_compatibility.rs +++ b/runtime/rust/prompty/tests/stream_chunk_compatibility.rs @@ -1,3 +1,7 @@ +use prompty::model::{ + LoadContext, SaveContext, StreamChunk as ModelStreamChunk, StreamChunkKind, + StreamFailure as ModelStreamFailure, StreamFailureOutcome, +}; use prompty::{StreamChunk, StreamFailure}; fn legacy_external_processor_error() -> StreamChunk { @@ -21,3 +25,31 @@ fn classified_failures_remain_available_for_indeterminate_reconciliation() { StreamChunk::Failure(failure) if failure.outcome_unknown() )); } + +#[test] +fn classified_failures_bridge_to_the_canonical_generated_model() { + let compatibility = StreamFailure::Indeterminate("connection reset".to_string()); + let canonical = compatibility.to_model(); + + assert_eq!(canonical.outcome, StreamFailureOutcome::Indeterminate); + assert_eq!(canonical.message, "connection reset"); + assert_eq!(StreamFailure::from_model(canonical.clone()), compatibility); + + let chunk = ModelStreamChunk { + kind: StreamChunkKind::FailureChunk { failure: canonical }, + }; + let saved = chunk.to_value(&SaveContext::default()); + let loaded = ModelStreamChunk::load_from_value(&saved, &LoadContext::default()); + assert_eq!(loaded, chunk); + + let StreamChunkKind::FailureChunk { failure } = loaded.kind else { + panic!("canonical failure chunk must retain its discriminator"); + }; + assert_eq!( + StreamFailure::from_model(ModelStreamFailure { + outcome: failure.outcome, + message: failure.message, + }), + compatibility + ); +} From fc23a1ac61d4475a87fa693bfa1290b12083ef24 Mon Sep 17 00:00:00 2001 From: Seth Juarez Date: Tue, 4 Aug 2026 00:50:19 -0700 Subject: [PATCH 03/10] feat(typescript): reconcile classified stream failures Emit generated failure chunks from provider streams and surface partial content plus reconciliation requirements without committing successful turns. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../packages/anthropic/src/processor.ts | 21 ++++- .../packages/core/src/core/index.ts | 1 + .../packages/core/src/core/pipeline.ts | 71 ++++++++++++++- runtime/typescript/packages/core/src/index.ts | 5 ++ .../core/tests/stream-failures.test.ts | 88 +++++++++++++++++++ .../packages/openai/src/processor.ts | 31 ++++++- .../tests/stream-failure-vectors.test.ts | 59 +++++++++++++ 7 files changed, 266 insertions(+), 10 deletions(-) create mode 100644 runtime/typescript/packages/core/tests/stream-failures.test.ts create mode 100644 runtime/typescript/packages/openai/tests/stream-failure-vectors.test.ts diff --git a/runtime/typescript/packages/anthropic/src/processor.ts b/runtime/typescript/packages/anthropic/src/processor.ts index 4b95b3890..7085ee515 100644 --- a/runtime/typescript/packages/anthropic/src/processor.ts +++ b/runtime/typescript/packages/anthropic/src/processor.ts @@ -13,6 +13,7 @@ import type { Prompty } from "@prompty/core"; import type { Processor } from "@prompty/core"; import type { ToolCall } from "@prompty/core"; +import { FailureChunk, StreamFailure } from "@prompty/core"; import { traceSpan } from "@prompty/core"; import { createStructuredResult } from "@prompty/core"; @@ -78,13 +79,29 @@ function isAsyncIterable(value: unknown): value is AsyncIterable { */ async function* streamGenerator( response: AsyncIterable, -): AsyncGenerator { +): AsyncGenerator { const toolCallAcc: Map< number, { id: string; name: string; arguments: string } > = new Map(); + const iterator = response[Symbol.asyncIterator](); - for await (const event of response) { + while (true) { + let next: IteratorResult; + try { + next = await iterator.next(); + } catch (error) { + yield new FailureChunk({ + failure: new StreamFailure({ + outcome: "indeterminate", + message: error instanceof Error ? error.message : String(error), + }), + }); + return; + } + if (next.done) break; + + const event = next.value; const e = event as Record; const eventType = e.type as string | undefined; diff --git a/runtime/typescript/packages/core/src/core/index.ts b/runtime/typescript/packages/core/src/core/index.ts index 8f12035f1..725d300f5 100644 --- a/runtime/typescript/packages/core/src/core/index.ts +++ b/runtime/typescript/packages/core/src/core/index.ts @@ -14,6 +14,7 @@ export { invoke, resolveBindings, ExecuteError, + StreamFailureError, type TurnOptions, type InvokeOptions, } from "./pipeline.js"; diff --git a/runtime/typescript/packages/core/src/core/pipeline.ts b/runtime/typescript/packages/core/src/core/pipeline.ts index fec4e56da..0fcb73ac5 100644 --- a/runtime/typescript/packages/core/src/core/pipeline.ts +++ b/runtime/typescript/packages/core/src/core/pipeline.ts @@ -32,6 +32,8 @@ */ import { Prompty } from "../model/agent/prompty.js"; +import { FailureChunk } from "../model/events/stream-chunk.js"; +import { StreamFailure } from "../model/events/stream-failure.js"; import { type ToolCall, Message, @@ -92,6 +94,24 @@ export class ExecuteError extends Error { } } +/** Terminal classified failure from a processed model stream. */ +export class StreamFailureError extends Error { + public readonly failure: StreamFailure; + public readonly partialContent: string; + + constructor(failure: StreamFailure, partialContent: string) { + super(failure.message); + this.name = "StreamFailureError"; + this.failure = failure; + this.partialContent = partialContent; + } + + /** Whether the provider outcome must be reconciled before another invocation. */ + get requiresReconciliation(): boolean { + return this.failure.outcome === "indeterminate"; + } +} + /** Replace raw nonce strings with readable `{{thread:name}}` in trace output. */ function sanitizeNonces(value: unknown): unknown { const nonces = getLastNonces(); @@ -766,9 +786,24 @@ export async function turn( } let processed: unknown; try { - processed = await process(agent, response); + if (isAsyncIterable(response)) { + const streamResult = await consumeStream(agent, response, onEvent); + processed = streamResult.content; + } else { + processed = await process(agent, response); + } } catch (err) { - emitFailedTurnEnd(onEvent, err, 0, response); + if (err instanceof StreamFailureError) { + emitEvent(onEvent, "error", { + message: err.message, + outcome: err.failure.outcome, + requiresReconciliation: err.requiresReconciliation, + partialContent: err.partialContent, + }); + emitFailedTurnEnd(onEvent, err, 0, err.partialContent); + } else { + emitFailedTurnEnd(onEvent, err, 0, response); + } throw err; } @@ -893,7 +928,17 @@ export async function turn( try { streamResult = await consumeStream(agent, response, onEvent); } catch (err) { - emitFailedTurnEnd(onEvent, err, iteration, response); + if (err instanceof StreamFailureError) { + emitEvent(onEvent, "error", { + message: err.message, + outcome: err.failure.outcome, + requiresReconciliation: err.requiresReconciliation, + partialContent: err.partialContent, + }); + emitFailedTurnEnd(onEvent, err, iteration, err.partialContent); + } else { + emitFailedTurnEnd(onEvent, err, iteration, response); + } throw err; } const { toolCalls, content } = streamResult; @@ -1097,7 +1142,10 @@ async function consumeStream( if (isAsyncIterable(processed)) { for await (const item of processed) { - if (isToolCallLike(item)) { + const failure = streamFailureFrom(item); + if (failure !== undefined) { + throw new StreamFailureError(failure, textParts.join("")); + } else if (isToolCallLike(item)) { toolCalls.push(item); } else if (typeof item === "string") { textParts.push(item); @@ -1112,6 +1160,21 @@ async function consumeStream( return { toolCalls, content: textParts.join("") }; } +function streamFailureFrom(item: unknown): StreamFailure | undefined { + if (item instanceof FailureChunk) { + return item.failure; + } + if (typeof item !== "object" || item === null) { + return undefined; + } + + const chunk = item as Record; + if (chunk.kind !== "failure" || typeof chunk.failure !== "object" || chunk.failure === null) { + return undefined; + } + return StreamFailure.load(chunk.failure as Record); +} + // --------------------------------------------------------------------------- // Thread marker helpers diff --git a/runtime/typescript/packages/core/src/index.ts b/runtime/typescript/packages/core/src/index.ts index 74c4da32b..b911dc2bf 100644 --- a/runtime/typescript/packages/core/src/index.ts +++ b/runtime/typescript/packages/core/src/index.ts @@ -69,6 +69,7 @@ export { turn, invoke, resolveBindings, + StreamFailureError, type TurnOptions, type InvokeOptions, @@ -197,6 +198,10 @@ export { PermissionDecision, HostToolRequest, HostToolResult, + StreamChunk, + ErrorChunk, + FailureChunk, + StreamFailure, type EventJournalWriter, type EventSink, type PermissionResolver, diff --git a/runtime/typescript/packages/core/tests/stream-failures.test.ts b/runtime/typescript/packages/core/tests/stream-failures.test.ts new file mode 100644 index 000000000..7f7238cab --- /dev/null +++ b/runtime/typescript/packages/core/tests/stream-failures.test.ts @@ -0,0 +1,88 @@ +import { readFileSync } from "node:fs"; +import { resolve } from "node:path"; + +import { OpenAIProcessor } from "@prompty/openai"; +import { beforeEach, describe, expect, it } from "vitest"; + +import type { EventCallback } from "../src/core/agent-events.js"; +import type { Executor } from "../src/core/interfaces.js"; +import { StreamFailureError, turn } from "../src/core/pipeline.js"; +import { + clearCache, + registerExecutor, + registerParser, + registerProcessor, + registerRenderer, +} from "../src/core/registry.js"; +import { Prompty } from "../src/model/agent/prompty.js"; +import { PromptyChatParser } from "../src/parsers/prompty.js"; +import { NunjucksRenderer } from "../src/renderers/nunjucks.js"; + +interface StreamFailureVector { + name: string; + input: { + events: Array<{ kind: "provider"; value: Record } | { kind: "transportError"; message: string }>; + }; + expected: { partialText: string; requiresReconciliation: boolean; completionCommitted: boolean }; +} + +const PROVIDER = "stream-failure-vector"; + +function loadVectors(): StreamFailureVector[] { + const path = resolve(import.meta.dirname, "../../../../../spec/vectors/process/stream_failure_vectors.json"); + return JSON.parse(readFileSync(path, "utf8")) as StreamFailureVector[]; +} + +class VectorExecutor implements Executor { + constructor(private readonly vector: StreamFailureVector) {} + + async execute(): Promise> { + const events = this.vector.input.events; + return { + async *[Symbol.asyncIterator](): AsyncIterator { + for (const event of events) { + if (event.kind === "transportError") { + throw new Error(event.message); + } + yield event.value; + } + }, + }; + } +} + +function makeAgent(): Prompty { + return Prompty.load({ + name: "stream-failure-vector", + model: { id: "gpt-test", provider: PROVIDER }, + instructions: "user:\nHello", + }); +} + +describe("turn classified stream failures", () => { + beforeEach(() => { + clearCache(); + registerRenderer("nunjucks", new NunjucksRenderer()); + registerParser("prompty", new PromptyChatParser()); + }); + + for (const vector of loadVectors()) { + it(vector.name, async () => { + registerExecutor(PROVIDER, new VectorExecutor(vector)); + registerProcessor(PROVIDER, new OpenAIProcessor()); + const events: Array<{ type: string; data: Record }> = []; + const onEvent: EventCallback = (type, data) => events.push({ type, data }); + + const error = await turn(makeAgent(), {}, { onEvent }).catch((caught: unknown) => caught); + + expect(error).toBeInstanceOf(StreamFailureError); + const failure = error as StreamFailureError; + expect(failure.partialContent).toBe(vector.expected.partialText); + expect(failure.requiresReconciliation).toBe(vector.expected.requiresReconciliation); + expect(events.some(event => event.type === "done")).toBe(vector.expected.completionCommitted); + expect(events.some(event => event.type === "turn_end" && event.data.status === "success")).toBe( + vector.expected.completionCommitted, + ); + }); + } +}); diff --git a/runtime/typescript/packages/openai/src/processor.ts b/runtime/typescript/packages/openai/src/processor.ts index 532e7e4c9..ac17bf03e 100644 --- a/runtime/typescript/packages/openai/src/processor.ts +++ b/runtime/typescript/packages/openai/src/processor.ts @@ -9,6 +9,7 @@ import type { Prompty } from "@prompty/core"; import type { Processor } from "@prompty/core"; import type { ToolCall } from "@prompty/core"; +import { FailureChunk, StreamFailure } from "@prompty/core"; import { traceSpan } from "@prompty/core"; import { createStructuredResult } from "@prompty/core"; @@ -86,16 +87,27 @@ function isAsyncIterable(value: unknown): value is AsyncIterable { * - `delta.content` — yields content strings * - `delta.tool_calls` — accumulates partial tool call chunks, * yields ToolCall objects when the stream ends - * - `delta.refusal` — throws Error with the refusal message + * - `delta.refusal` — yields a determinate FailureChunk * * Matches the Python `_stream_generator` / `_async_stream_generator`. */ async function* streamGenerator( response: AsyncIterable, -): AsyncGenerator { +): AsyncGenerator { const toolCallAcc: Map = new Map(); + const iterator = response[Symbol.asyncIterator](); - for await (const chunk of response) { + while (true) { + let next: IteratorResult; + try { + next = await iterator.next(); + } catch (error) { + yield failureChunk("indeterminate", errorMessage(error)); + return; + } + if (next.done) break; + + const chunk = next.value; const c = chunk as Record; const choices = c.choices as Record[] | undefined; if (!choices || choices.length === 0) continue; @@ -128,7 +140,8 @@ async function* streamGenerator( // Refusal if (delta.refusal != null) { - throw new Error(`Model refused: ${delta.refusal}`); + yield failureChunk("determinate", `Model refused: ${delta.refusal}`); + return; } } @@ -140,6 +153,16 @@ async function* streamGenerator( } } +function failureChunk(outcome: "determinate" | "indeterminate", message: string): FailureChunk { + return new FailureChunk({ + failure: new StreamFailure({ outcome, message }), + }); +} + +function errorMessage(error: unknown): string { + return error instanceof Error ? error.message : String(error); +} + // --------------------------------------------------------------------------- // Responses API processing // --------------------------------------------------------------------------- diff --git a/runtime/typescript/packages/openai/tests/stream-failure-vectors.test.ts b/runtime/typescript/packages/openai/tests/stream-failure-vectors.test.ts new file mode 100644 index 000000000..5cc2fcf62 --- /dev/null +++ b/runtime/typescript/packages/openai/tests/stream-failure-vectors.test.ts @@ -0,0 +1,59 @@ +import { readFileSync } from "node:fs"; +import { resolve } from "node:path"; + +import { FailureChunk, Prompty, StreamChunk } from "@prompty/core"; +import { describe, expect, it } from "vitest"; + +import { processResponse } from "../src/processor.js"; + +interface StreamFailureVector { + name: string; + input: { + provider: string; + events: Array<{ kind: "provider"; value: Record } | { kind: "transportError"; message: string }>; + }; + expected: { chunks: unknown[] }; +} + +function loadVectors(): StreamFailureVector[] { + const path = resolve(import.meta.dirname, "../../../../../spec/vectors/process/stream_failure_vectors.json"); + return JSON.parse(readFileSync(path, "utf8")) as StreamFailureVector[]; +} + +function responseFromVector(vector: StreamFailureVector): AsyncIterable { + return { + async *[Symbol.asyncIterator](): AsyncIterator { + for (const event of vector.input.events) { + if (event.kind === "transportError") { + throw new Error(event.message); + } + yield event.value; + } + }, + }; +} + +describe("OpenAI classified stream failure vectors", () => { + for (const vector of loadVectors()) { + it(vector.name, async () => { + expect(vector.input.provider).toBe("openai"); + const agent = new Prompty({ name: "stream-vector", model: "gpt-test" }); + const processed = processResponse(agent, responseFromVector(vector)); + const actual: unknown[] = []; + + for await (const item of processed as AsyncIterable) { + if (item instanceof FailureChunk) { + const saved = item.save(); + const loaded = StreamChunk.load(saved); + expect(loaded).toBeInstanceOf(FailureChunk); + expect(loaded.save()).toEqual(saved); + actual.push(saved); + } else { + actual.push({ kind: "text", value: item }); + } + } + + expect(actual).toEqual(vector.expected.chunks); + }); + } +}); From 22351d01957c9a1e52acb89e8d0620b7599b0b74 Mon Sep 17 00:00:00 2001 From: Seth Juarez Date: Tue, 4 Aug 2026 02:04:03 -0700 Subject: [PATCH 04/10] fix(typescript): close failed provider streams Cancel upstream async iterators before yielding terminal failure chunks so SSE resources are released without masking the classified failure. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../packages/anthropic/src/processor.ts | 12 ++++++ .../anthropic/tests/stream-failures.test.ts | 37 ++++++++++++++++ .../packages/openai/src/processor.ts | 13 ++++++ .../tests/stream-failure-vectors.test.ts | 43 +++++++++++++++++++ 4 files changed, 105 insertions(+) create mode 100644 runtime/typescript/packages/anthropic/tests/stream-failures.test.ts diff --git a/runtime/typescript/packages/anthropic/src/processor.ts b/runtime/typescript/packages/anthropic/src/processor.ts index 7085ee515..851140d0e 100644 --- a/runtime/typescript/packages/anthropic/src/processor.ts +++ b/runtime/typescript/packages/anthropic/src/processor.ts @@ -91,6 +91,7 @@ async function* streamGenerator( try { next = await iterator.next(); } catch (error) { + await closeIterator(iterator); yield new FailureChunk({ failure: new StreamFailure({ outcome: "indeterminate", @@ -140,6 +141,17 @@ async function* streamGenerator( } } +async function closeIterator(iterator: AsyncIterator): Promise { + if (!iterator.return) return; + try { + await iterator.return(); + } catch (error) { + if (typeof globalThis.console?.debug === "function") { + globalThis.console.debug("Failed to close Anthropic response stream:", error); + } + } +} + // --------------------------------------------------------------------------- // Non-streaming response processing // --------------------------------------------------------------------------- diff --git a/runtime/typescript/packages/anthropic/tests/stream-failures.test.ts b/runtime/typescript/packages/anthropic/tests/stream-failures.test.ts new file mode 100644 index 000000000..d8147bb5f --- /dev/null +++ b/runtime/typescript/packages/anthropic/tests/stream-failures.test.ts @@ -0,0 +1,37 @@ +import { FailureChunk, Prompty } from "@prompty/core"; +import { describe, expect, it } from "vitest"; + +import { processResponse } from "../src/processor.js"; + +describe("Anthropic classified stream failures", () => { + it("closes the provider stream after a transport failure", async () => { + let closed = false; + const response: AsyncIterable = { + [Symbol.asyncIterator](): AsyncIterator { + return { + async next(): Promise> { + throw new Error("SSE stream error: connection reset"); + }, + async return(): Promise> { + closed = true; + return { done: true, value: undefined }; + }, + }; + }, + }; + const agent = new Prompty({ name: "stream-failure", model: "claude-test" }); + const processed = processResponse(agent, response); + const chunks: unknown[] = []; + + for await (const chunk of processed as AsyncIterable) { + chunks.push(chunk); + } + + expect(closed).toBe(true); + expect(chunks).toHaveLength(1); + expect(chunks[0]).toBeInstanceOf(FailureChunk); + const failure = chunks[0] as FailureChunk; + expect(failure.failure.outcome).toBe("indeterminate"); + expect(failure.failure.message).toBe("SSE stream error: connection reset"); + }); +}); diff --git a/runtime/typescript/packages/openai/src/processor.ts b/runtime/typescript/packages/openai/src/processor.ts index ac17bf03e..21165e4ca 100644 --- a/runtime/typescript/packages/openai/src/processor.ts +++ b/runtime/typescript/packages/openai/src/processor.ts @@ -102,6 +102,7 @@ async function* streamGenerator( try { next = await iterator.next(); } catch (error) { + await closeIterator(iterator); yield failureChunk("indeterminate", errorMessage(error)); return; } @@ -140,6 +141,7 @@ async function* streamGenerator( // Refusal if (delta.refusal != null) { + await closeIterator(iterator); yield failureChunk("determinate", `Model refused: ${delta.refusal}`); return; } @@ -163,6 +165,17 @@ function errorMessage(error: unknown): string { return error instanceof Error ? error.message : String(error); } +async function closeIterator(iterator: AsyncIterator): Promise { + if (!iterator.return) return; + try { + await iterator.return(); + } catch (error) { + if (typeof globalThis.console?.debug === "function") { + globalThis.console.debug("Failed to close OpenAI response stream:", error); + } + } +} + // --------------------------------------------------------------------------- // Responses API processing // --------------------------------------------------------------------------- diff --git a/runtime/typescript/packages/openai/tests/stream-failure-vectors.test.ts b/runtime/typescript/packages/openai/tests/stream-failure-vectors.test.ts index 5cc2fcf62..af693e955 100644 --- a/runtime/typescript/packages/openai/tests/stream-failure-vectors.test.ts +++ b/runtime/typescript/packages/openai/tests/stream-failure-vectors.test.ts @@ -33,6 +33,32 @@ function responseFromVector(vector: StreamFailureVector): AsyncIterable }; } +function closableResponseFromVector( + vector: StreamFailureVector, + onClose: () => void, +): AsyncIterable { + const events = vector.input.events; + let index = 0; + return { + [Symbol.asyncIterator](): AsyncIterator { + return { + async next(): Promise> { + const event = events[index++]; + if (event === undefined) return { done: true, value: undefined }; + if (event.kind === "transportError") { + throw new Error(event.message); + } + return { done: false, value: event.value }; + }, + async return(): Promise> { + onClose(); + return { done: true, value: undefined }; + }, + }; + }, + }; +} + describe("OpenAI classified stream failure vectors", () => { for (const vector of loadVectors()) { it(vector.name, async () => { @@ -55,5 +81,22 @@ describe("OpenAI classified stream failure vectors", () => { expect(actual).toEqual(vector.expected.chunks); }); + + it(`${vector.name} closes the provider stream`, async () => { + let closed = false; + const agent = new Prompty({ name: "stream-vector", model: "gpt-test" }); + const processed = processResponse( + agent, + closableResponseFromVector(vector, () => { + closed = true; + }), + ); + + for await (const _ of processed as AsyncIterable) { + // Consume the terminal failure chunk. + } + + expect(closed).toBe(true); + }); } }); From 8d0ddac0d057503c1e151e9cca104c6e4d27550a Mon Sep 17 00:00:00 2001 From: Seth Juarez Date: Tue, 4 Aug 2026 02:04:04 -0700 Subject: [PATCH 05/10] fix(harness): journal denied tool results Record permission denials as committed tool results across reference runners without emitting tool execution events. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- runtime/csharp/Prompty.Core/TurnRunner.cs | 4 +++- runtime/go/prompty/model/turn_runner.go | 8 ++++++-- runtime/python/prompty/prompty/harness/turn_runner.py | 4 +++- .../typescript/packages/core/src/harness/turn-runner.ts | 4 +++- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/runtime/csharp/Prompty.Core/TurnRunner.cs b/runtime/csharp/Prompty.Core/TurnRunner.cs index 928caaac5..c00460ef5 100644 --- a/runtime/csharp/Prompty.Core/TurnRunner.cs +++ b/runtime/csharp/Prompty.Core/TurnRunner.cs @@ -189,7 +189,7 @@ private async Task ResolveAndExecuteToolAsync(string turnId, int if (!decision.Approved) { - return new HostToolResult + var deniedResult = new HostToolResult { RequestId = toolRequest.RequestId, ToolCallId = toolRequest.ToolCallId, @@ -198,6 +198,8 @@ private async Task ResolveAndExecuteToolAsync(string turnId, int ErrorKind = "permission_denied", Result = new Dictionary { ["message"] = decision.Reason ?? "Permission denied" } }; + RecordTurn(TurnEventType.ToolResult, turnId, iteration, deniedResult.Save()); + return deniedResult; } RecordTurn(TurnEventType.ToolExecutionStart, turnId, iteration, toolRequest.Save()); diff --git a/runtime/go/prompty/model/turn_runner.go b/runtime/go/prompty/model/turn_runner.go index 5c573bfa2..f30cd5fca 100644 --- a/runtime/go/prompty/model/turn_runner.go +++ b/runtime/go/prompty/model/turn_runner.go @@ -223,14 +223,18 @@ func (r *ReferenceTurnRunner) resolveAndExecuteTool(turnId string, iteration int message = *decision.Reason } result := interface{}(map[string]interface{}{"message": message}) - return HostToolResult{ + toolResult := HostToolResult{ RequestId: toolRequest.RequestId, ToolCallId: toolRequest.ToolCallId, ToolName: toolRequest.ToolName, Success: false, ErrorKind: &errorKind, Result: &result, - }, nil + } + if err := r.recordTurn(TurnEventTypeToolResult, turnId, iteration, toolResult.Save(NewSaveContext())); err != nil { + return HostToolResult{}, err + } + return toolResult, nil } if err := r.recordTurn(TurnEventTypeToolExecutionStart, turnId, iteration, toolRequest.Save(NewSaveContext())); err != nil { return HostToolResult{}, err diff --git a/runtime/python/prompty/prompty/harness/turn_runner.py b/runtime/python/prompty/prompty/harness/turn_runner.py index 0b9ecdef5..2fac17008 100644 --- a/runtime/python/prompty/prompty/harness/turn_runner.py +++ b/runtime/python/prompty/prompty/harness/turn_runner.py @@ -243,7 +243,7 @@ async def _resolve_and_execute_tool( self._record_turn("permission_completed", turn_id, iteration, decision.save()) if not decision.approved: - return HostToolResult( + result = HostToolResult( request_id=tool_request.request_id, tool_call_id=tool_request.tool_call_id, tool_name=tool_request.tool_name, @@ -251,6 +251,8 @@ async def _resolve_and_execute_tool( error_kind="permission_denied", result={"message": decision.reason or "Permission denied"}, ) + self._record_turn("tool_result", turn_id, iteration, result.save()) + return result self._record_turn("tool_execution_start", turn_id, iteration, tool_request.save()) result = await self.host_tool_executor.execute(tool_request) diff --git a/runtime/typescript/packages/core/src/harness/turn-runner.ts b/runtime/typescript/packages/core/src/harness/turn-runner.ts index a650c1830..9ecf23fb7 100644 --- a/runtime/typescript/packages/core/src/harness/turn-runner.ts +++ b/runtime/typescript/packages/core/src/harness/turn-runner.ts @@ -185,7 +185,7 @@ export class ReferenceTurnRunner { this.recordTurn("permission_completed", turnId, iteration, decision.save()); if (!decision.approved) { - return new HostToolResult({ + const result = new HostToolResult({ requestId: toolRequest.requestId, toolCallId: toolRequest.toolCallId, toolName: toolRequest.toolName, @@ -193,6 +193,8 @@ export class ReferenceTurnRunner { errorKind: "permission_denied", result: { message: decision.reason ?? "Permission denied" }, }); + this.recordTurn("tool_result", turnId, iteration, result.save()); + return result; } this.recordTurn("tool_execution_start", turnId, iteration, toolRequest.save()); From 8a04ccc5e8dc6f17995fe10b65a541c293213f2e Mon Sep 17 00:00:00 2001 From: Seth Juarez Date: Tue, 4 Aug 2026 02:04:04 -0700 Subject: [PATCH 06/10] fix(schema): normalize prompt sample whitespace Remove trailing spaces from the canonical instruction sample so generated JSON round-trip fixtures agree across runtimes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../Model/agent/PromptyConversionTests.cs | 144 +++---- runtime/go/prompty/model/prompty_test.go | 368 +++++++++--------- .../prompty/tests/model/agent/test_prompty.py | 96 ++--- .../prompty/tests/model/agent/prompty_test.rs | 110 +++--- .../core/tests/model/agent/prompty.test.ts | 96 ++--- schema/model/agent/agent.tsp | 4 +- schema/tsp-output/json-ast/model.json | 2 +- 7 files changed, 410 insertions(+), 410 deletions(-) diff --git a/runtime/csharp/Prompty.Core.Tests/Model/agent/PromptyConversionTests.cs b/runtime/csharp/Prompty.Core.Tests/Model/agent/PromptyConversionTests.cs index af121fe9f..aeb764adf 100644 --- a/runtime/csharp/Prompty.Core.Tests/Model/agent/PromptyConversionTests.cs +++ b/runtime/csharp/Prompty.Core.Tests/Model/agent/PromptyConversionTests.cs @@ -62,14 +62,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -165,7 +165,7 @@ public void LoadJsonInput() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -255,7 +255,7 @@ public void RoundtripJson() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -338,14 +338,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -446,7 +446,7 @@ public void ToJsonProducesValidJson() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -512,14 +512,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -591,14 +591,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -693,7 +693,7 @@ public void LoadJsonInput1() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -782,7 +782,7 @@ public void RoundtripJson1() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -865,14 +865,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -972,7 +972,7 @@ public void ToJsonProducesValidJson1() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -1038,14 +1038,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -1117,14 +1117,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -1221,7 +1221,7 @@ public void LoadJsonInput2() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -1312,7 +1312,7 @@ public void RoundtripJson2() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -1395,14 +1395,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -1504,7 +1504,7 @@ public void ToJsonProducesValidJson2() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -1570,14 +1570,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -1649,14 +1649,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -1752,7 +1752,7 @@ public void LoadJsonInput3() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -1842,7 +1842,7 @@ public void RoundtripJson3() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -1925,14 +1925,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -2033,7 +2033,7 @@ public void ToJsonProducesValidJson3() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -2099,14 +2099,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -2178,14 +2178,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -2284,7 +2284,7 @@ public void LoadJsonInput4() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -2377,7 +2377,7 @@ public void RoundtripJson4() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -2460,14 +2460,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -2571,7 +2571,7 @@ public void ToJsonProducesValidJson4() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -2637,14 +2637,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -2716,14 +2716,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -2821,7 +2821,7 @@ public void LoadJsonInput5() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -2913,7 +2913,7 @@ public void RoundtripJson5() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -2996,14 +2996,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -3106,7 +3106,7 @@ public void ToJsonProducesValidJson5() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -3172,14 +3172,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -3251,14 +3251,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -3358,7 +3358,7 @@ public void LoadJsonInput6() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -3452,7 +3452,7 @@ public void RoundtripJson6() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -3535,14 +3535,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -3647,7 +3647,7 @@ public void ToJsonProducesValidJson6() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -3713,14 +3713,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -3792,14 +3792,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -3898,7 +3898,7 @@ public void LoadJsonInput7() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -3991,7 +3991,7 @@ public void RoundtripJson7() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -4074,14 +4074,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -4185,7 +4185,7 @@ public void ToJsonProducesValidJson7() "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """; @@ -4251,14 +4251,14 @@ You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. diff --git a/runtime/go/prompty/model/prompty_test.go b/runtime/go/prompty/model/prompty_test.go index ab4a9094d..94b365208 100644 --- a/runtime/go/prompty/model/prompty_test.go +++ b/runtime/go/prompty/model/prompty_test.go @@ -79,7 +79,7 @@ func TestPromptyLoadJSON(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -101,8 +101,8 @@ func TestPromptyLoadJSON(t *testing.T) { if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -181,14 +181,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -216,8 +216,8 @@ instructions: "system: if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -309,7 +309,7 @@ func TestPromptyFromJSON(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` @@ -326,8 +326,8 @@ func TestPromptyFromJSON(t *testing.T) { if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -406,14 +406,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -436,8 +436,8 @@ instructions: "system: if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -529,7 +529,7 @@ func TestPromptyRoundtrip(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -558,8 +558,8 @@ func TestPromptyRoundtrip(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -651,7 +651,7 @@ func TestPromptyToJSON(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -687,8 +687,8 @@ func TestPromptyToJSON(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -780,7 +780,7 @@ func TestPromptyToYAML(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -816,8 +816,8 @@ func TestPromptyToYAML(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -908,7 +908,7 @@ func TestPromptyLoadJSON1(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -930,8 +930,8 @@ func TestPromptyLoadJSON1(t *testing.T) { if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -1000,14 +1000,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -1035,8 +1035,8 @@ instructions: "system: if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -1117,7 +1117,7 @@ func TestPromptyFromJSON1(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` @@ -1134,8 +1134,8 @@ func TestPromptyFromJSON1(t *testing.T) { if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -1204,14 +1204,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -1234,8 +1234,8 @@ instructions: "system: if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -1316,7 +1316,7 @@ func TestPromptyRoundtrip1(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -1345,8 +1345,8 @@ func TestPromptyRoundtrip1(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -1427,7 +1427,7 @@ func TestPromptyToJSON1(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -1463,8 +1463,8 @@ func TestPromptyToJSON1(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -1545,7 +1545,7 @@ func TestPromptyToYAML1(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -1581,8 +1581,8 @@ func TestPromptyToYAML1(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -1665,7 +1665,7 @@ func TestPromptyLoadJSON2(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -1687,8 +1687,8 @@ func TestPromptyLoadJSON2(t *testing.T) { if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -1770,14 +1770,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -1805,8 +1805,8 @@ instructions: "system: if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -1902,7 +1902,7 @@ func TestPromptyFromJSON2(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` @@ -1919,8 +1919,8 @@ func TestPromptyFromJSON2(t *testing.T) { if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -2002,14 +2002,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -2032,8 +2032,8 @@ instructions: "system: if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -2129,7 +2129,7 @@ func TestPromptyRoundtrip2(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -2158,8 +2158,8 @@ func TestPromptyRoundtrip2(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -2255,7 +2255,7 @@ func TestPromptyToJSON2(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -2291,8 +2291,8 @@ func TestPromptyToJSON2(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -2388,7 +2388,7 @@ func TestPromptyToYAML2(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -2424,8 +2424,8 @@ func TestPromptyToYAML2(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -2520,7 +2520,7 @@ func TestPromptyLoadJSON3(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -2542,8 +2542,8 @@ func TestPromptyLoadJSON3(t *testing.T) { if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -2615,14 +2615,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -2650,8 +2650,8 @@ instructions: "system: if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -2736,7 +2736,7 @@ func TestPromptyFromJSON3(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` @@ -2753,8 +2753,8 @@ func TestPromptyFromJSON3(t *testing.T) { if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -2826,14 +2826,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -2856,8 +2856,8 @@ instructions: "system: if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -2942,7 +2942,7 @@ func TestPromptyRoundtrip3(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -2971,8 +2971,8 @@ func TestPromptyRoundtrip3(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -3057,7 +3057,7 @@ func TestPromptyToJSON3(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -3093,8 +3093,8 @@ func TestPromptyToJSON3(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -3179,7 +3179,7 @@ func TestPromptyToYAML3(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -3215,8 +3215,8 @@ func TestPromptyToYAML3(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -3304,7 +3304,7 @@ func TestPromptyLoadJSON4(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -3326,8 +3326,8 @@ func TestPromptyLoadJSON4(t *testing.T) { if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -3418,14 +3418,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -3453,8 +3453,8 @@ instructions: "system: if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -3561,7 +3561,7 @@ func TestPromptyFromJSON4(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` @@ -3578,8 +3578,8 @@ func TestPromptyFromJSON4(t *testing.T) { if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -3670,14 +3670,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -3700,8 +3700,8 @@ instructions: "system: if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -3808,7 +3808,7 @@ func TestPromptyRoundtrip4(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -3837,8 +3837,8 @@ func TestPromptyRoundtrip4(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -3945,7 +3945,7 @@ func TestPromptyToJSON4(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -3981,8 +3981,8 @@ func TestPromptyToJSON4(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -4089,7 +4089,7 @@ func TestPromptyToYAML4(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -4125,8 +4125,8 @@ func TestPromptyToYAML4(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -4232,7 +4232,7 @@ func TestPromptyLoadJSON5(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -4254,8 +4254,8 @@ func TestPromptyLoadJSON5(t *testing.T) { if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -4336,14 +4336,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -4371,8 +4371,8 @@ instructions: "system: if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -4468,7 +4468,7 @@ func TestPromptyFromJSON5(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` @@ -4485,8 +4485,8 @@ func TestPromptyFromJSON5(t *testing.T) { if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -4567,14 +4567,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -4597,8 +4597,8 @@ instructions: "system: if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -4694,7 +4694,7 @@ func TestPromptyRoundtrip5(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -4723,8 +4723,8 @@ func TestPromptyRoundtrip5(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -4820,7 +4820,7 @@ func TestPromptyToJSON5(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -4856,8 +4856,8 @@ func TestPromptyToJSON5(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -4953,7 +4953,7 @@ func TestPromptyToYAML5(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -4989,8 +4989,8 @@ func TestPromptyToYAML5(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -5088,7 +5088,7 @@ func TestPromptyLoadJSON6(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -5110,8 +5110,8 @@ func TestPromptyLoadJSON6(t *testing.T) { if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -5205,14 +5205,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -5240,8 +5240,8 @@ instructions: "system: if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -5352,7 +5352,7 @@ func TestPromptyFromJSON6(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` @@ -5369,8 +5369,8 @@ func TestPromptyFromJSON6(t *testing.T) { if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -5464,14 +5464,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -5494,8 +5494,8 @@ instructions: "system: if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -5606,7 +5606,7 @@ func TestPromptyRoundtrip6(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -5635,8 +5635,8 @@ func TestPromptyRoundtrip6(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -5747,7 +5747,7 @@ func TestPromptyToJSON6(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -5783,8 +5783,8 @@ func TestPromptyToJSON6(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -5895,7 +5895,7 @@ func TestPromptyToYAML6(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -5931,8 +5931,8 @@ func TestPromptyToYAML6(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -6042,7 +6042,7 @@ func TestPromptyLoadJSON7(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -6064,8 +6064,8 @@ func TestPromptyLoadJSON7(t *testing.T) { if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -6149,14 +6149,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -6184,8 +6184,8 @@ instructions: "system: if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -6285,7 +6285,7 @@ func TestPromptyFromJSON7(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` @@ -6302,8 +6302,8 @@ func TestPromptyFromJSON7(t *testing.T) { if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -6387,14 +6387,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -6417,8 +6417,8 @@ instructions: "system: if instance.Description == nil || *instance.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, instance.Description) } - if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) + if instance.Instructions == nil || *instance.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, instance.Instructions) } if instance.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -6518,7 +6518,7 @@ func TestPromptyRoundtrip7(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -6547,8 +6547,8 @@ func TestPromptyRoundtrip7(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -6648,7 +6648,7 @@ func TestPromptyToJSON7(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -6684,8 +6684,8 @@ func TestPromptyToJSON7(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") @@ -6785,7 +6785,7 @@ func TestPromptyToYAML7(t *testing.T) { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } ` var data map[string]interface{} @@ -6821,8 +6821,8 @@ func TestPromptyToYAML7(t *testing.T) { if reloaded.Description == nil || *reloaded.Description != "A basic prompt that uses the GPT-3 chat API to answer questions" { t.Errorf(`Expected Description to be "A basic prompt that uses the GPT-3 chat API to answer questions", got %v`, reloaded.Description) } - if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { - t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) + if reloaded.Instructions == nil || *reloaded.Instructions != "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" { + t.Errorf(`Expected Instructions to be "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", got %v`, reloaded.Instructions) } if reloaded.Metadata == nil { t.Fatalf("Expected Metadata to be populated") diff --git a/runtime/python/prompty/tests/model/agent/test_prompty.py b/runtime/python/prompty/tests/model/agent/test_prompty.py index 056dc288b..22c58cb74 100644 --- a/runtime/python/prompty/tests/model/agent/test_prompty.py +++ b/runtime/python/prompty/tests/model/agent/test_prompty.py @@ -71,7 +71,7 @@ def test_load_json_prompty(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -148,14 +148,14 @@ def test_load_yaml_prompty(): As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -252,7 +252,7 @@ def test_roundtrip_json_prompty(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ original_data = json.loads(json_data, strict=False) @@ -345,7 +345,7 @@ def test_to_json_prompty(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -422,7 +422,7 @@ def test_to_yaml_prompty(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -497,7 +497,7 @@ def test_load_json_prompty_1(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -574,14 +574,14 @@ def test_load_yaml_prompty_1(): As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -677,7 +677,7 @@ def test_roundtrip_json_prompty_1(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ original_data = json.loads(json_data, strict=False) @@ -769,7 +769,7 @@ def test_to_json_prompty_1(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -845,7 +845,7 @@ def test_to_yaml_prompty_1(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -922,7 +922,7 @@ def test_load_json_prompty_2(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -999,14 +999,14 @@ def test_load_yaml_prompty_2(): As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -1104,7 +1104,7 @@ def test_roundtrip_json_prompty_2(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ original_data = json.loads(json_data, strict=False) @@ -1198,7 +1198,7 @@ def test_to_json_prompty_2(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -1276,7 +1276,7 @@ def test_to_yaml_prompty_2(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -1352,7 +1352,7 @@ def test_load_json_prompty_3(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -1429,14 +1429,14 @@ def test_load_yaml_prompty_3(): As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -1533,7 +1533,7 @@ def test_roundtrip_json_prompty_3(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ original_data = json.loads(json_data, strict=False) @@ -1626,7 +1626,7 @@ def test_to_json_prompty_3(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -1703,7 +1703,7 @@ def test_to_yaml_prompty_3(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -1782,7 +1782,7 @@ def test_load_json_prompty_4(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -1859,14 +1859,14 @@ def test_load_yaml_prompty_4(): As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -1966,7 +1966,7 @@ def test_roundtrip_json_prompty_4(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ original_data = json.loads(json_data, strict=False) @@ -2062,7 +2062,7 @@ def test_to_json_prompty_4(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -2142,7 +2142,7 @@ def test_to_yaml_prompty_4(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -2220,7 +2220,7 @@ def test_load_json_prompty_5(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -2297,14 +2297,14 @@ def test_load_yaml_prompty_5(): As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -2403,7 +2403,7 @@ def test_roundtrip_json_prompty_5(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ original_data = json.loads(json_data, strict=False) @@ -2498,7 +2498,7 @@ def test_to_json_prompty_5(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -2577,7 +2577,7 @@ def test_to_yaml_prompty_5(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -2657,7 +2657,7 @@ def test_load_json_prompty_6(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -2734,14 +2734,14 @@ def test_load_yaml_prompty_6(): As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -2842,7 +2842,7 @@ def test_roundtrip_json_prompty_6(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ original_data = json.loads(json_data, strict=False) @@ -2939,7 +2939,7 @@ def test_to_json_prompty_6(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -3020,7 +3020,7 @@ def test_to_yaml_prompty_6(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -3099,7 +3099,7 @@ def test_load_json_prompty_7(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -3176,14 +3176,14 @@ def test_load_yaml_prompty_7(): As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -3283,7 +3283,7 @@ def test_roundtrip_json_prompty_7(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ original_data = json.loads(json_data, strict=False) @@ -3379,7 +3379,7 @@ def test_to_json_prompty_7(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) @@ -3459,7 +3459,7 @@ def test_to_yaml_prompty_7(): "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } """ data = json.loads(json_data, strict=False) diff --git a/runtime/rust/prompty/tests/model/agent/prompty_test.rs b/runtime/rust/prompty/tests/model/agent/prompty_test.rs index a0a8ab299..c522577d1 100644 --- a/runtime/rust/prompty/tests/model/agent/prompty_test.rs +++ b/runtime/rust/prompty/tests/model/agent/prompty_test.rs @@ -78,7 +78,7 @@ fn test_prompty_load_json() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let ctx = LoadContext::default(); @@ -109,7 +109,7 @@ fn test_prompty_load_json() { ); assert_eq!( instance.instructions.as_ref().unwrap(), - &"system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + &"system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" ); } @@ -166,14 +166,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -271,7 +271,7 @@ fn test_prompty_roundtrip() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let load_ctx = LoadContext::default(); @@ -353,7 +353,7 @@ fn test_prompty_serde_roundtrip() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let instance: Prompty = @@ -465,7 +465,7 @@ fn test_prompty_serde_roundtrip() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let from_map: Prompty = serde_json::from_str(map_json) @@ -550,7 +550,7 @@ fn test_prompty_load_json_1() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let ctx = LoadContext::default(); @@ -581,7 +581,7 @@ fn test_prompty_load_json_1() { ); assert_eq!( instance.instructions.as_ref().unwrap(), - &"system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + &"system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" ); } @@ -638,14 +638,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -742,7 +742,7 @@ fn test_prompty_roundtrip_1() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let load_ctx = LoadContext::default(); @@ -823,7 +823,7 @@ fn test_prompty_serde_roundtrip_1() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let instance: Prompty = @@ -941,7 +941,7 @@ fn test_prompty_load_json_2() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let ctx = LoadContext::default(); @@ -972,7 +972,7 @@ fn test_prompty_load_json_2() { ); assert_eq!( instance.instructions.as_ref().unwrap(), - &"system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + &"system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" ); } @@ -1029,14 +1029,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -1135,7 +1135,7 @@ fn test_prompty_roundtrip_2() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let load_ctx = LoadContext::default(); @@ -1218,7 +1218,7 @@ fn test_prompty_serde_roundtrip_2() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let instance: Prompty = @@ -1330,7 +1330,7 @@ fn test_prompty_serde_roundtrip_2() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let from_map: Prompty = serde_json::from_str(map_json) @@ -1423,7 +1423,7 @@ fn test_prompty_load_json_3() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let ctx = LoadContext::default(); @@ -1454,7 +1454,7 @@ fn test_prompty_load_json_3() { ); assert_eq!( instance.instructions.as_ref().unwrap(), - &"system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + &"system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" ); } @@ -1511,14 +1511,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -1616,7 +1616,7 @@ fn test_prompty_roundtrip_3() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let load_ctx = LoadContext::default(); @@ -1698,7 +1698,7 @@ fn test_prompty_serde_roundtrip_3() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let instance: Prompty = @@ -1810,7 +1810,7 @@ fn test_prompty_serde_roundtrip_3() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let from_map: Prompty = serde_json::from_str(map_json) @@ -1899,7 +1899,7 @@ fn test_prompty_load_json_4() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let ctx = LoadContext::default(); @@ -1930,7 +1930,7 @@ fn test_prompty_load_json_4() { ); assert_eq!( instance.instructions.as_ref().unwrap(), - &"system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + &"system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" ); } @@ -1987,14 +1987,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -2095,7 +2095,7 @@ fn test_prompty_roundtrip_4() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let load_ctx = LoadContext::default(); @@ -2180,7 +2180,7 @@ fn test_prompty_serde_roundtrip_4() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let instance: Prompty = @@ -2292,7 +2292,7 @@ fn test_prompty_serde_roundtrip_4() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let from_map: Prompty = serde_json::from_str(map_json) @@ -2387,7 +2387,7 @@ fn test_prompty_load_json_5() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let ctx = LoadContext::default(); @@ -2418,7 +2418,7 @@ fn test_prompty_load_json_5() { ); assert_eq!( instance.instructions.as_ref().unwrap(), - &"system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + &"system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" ); } @@ -2475,14 +2475,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -2582,7 +2582,7 @@ fn test_prompty_roundtrip_5() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let load_ctx = LoadContext::default(); @@ -2666,7 +2666,7 @@ fn test_prompty_serde_roundtrip_5() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let instance: Prompty = @@ -2778,7 +2778,7 @@ fn test_prompty_serde_roundtrip_5() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let from_map: Prompty = serde_json::from_str(map_json) @@ -2868,7 +2868,7 @@ fn test_prompty_load_json_6() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let ctx = LoadContext::default(); @@ -2899,7 +2899,7 @@ fn test_prompty_load_json_6() { ); assert_eq!( instance.instructions.as_ref().unwrap(), - &"system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + &"system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" ); } @@ -2956,14 +2956,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -3065,7 +3065,7 @@ fn test_prompty_roundtrip_6() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let load_ctx = LoadContext::default(); @@ -3151,7 +3151,7 @@ fn test_prompty_serde_roundtrip_6() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let instance: Prompty = @@ -3263,7 +3263,7 @@ fn test_prompty_serde_roundtrip_6() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let from_map: Prompty = serde_json::from_str(map_json) @@ -3366,7 +3366,7 @@ fn test_prompty_load_json_7() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let ctx = LoadContext::default(); @@ -3397,7 +3397,7 @@ fn test_prompty_load_json_7() { ); assert_eq!( instance.instructions.as_ref().unwrap(), - &"system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + &"system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" ); } @@ -3454,14 +3454,14 @@ instructions: "system: As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some\ + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to\ + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. @@ -3562,7 +3562,7 @@ fn test_prompty_roundtrip_7() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let load_ctx = LoadContext::default(); @@ -3647,7 +3647,7 @@ fn test_prompty_serde_roundtrip_7() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let instance: Prompty = @@ -3759,7 +3759,7 @@ fn test_prompty_serde_roundtrip_7() { "format": "mustache", "parser": "prompty" }, - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" } "####; let from_map: Prompty = serde_json::from_str(map_json) diff --git a/runtime/typescript/packages/core/tests/model/agent/prompty.test.ts b/runtime/typescript/packages/core/tests/model/agent/prompty.test.ts index 401cb72e0..cf7e84dab 100644 --- a/runtime/typescript/packages/core/tests/model/agent/prompty.test.ts +++ b/runtime/typescript/packages/core/tests/model/agent/prompty.test.ts @@ -19,7 +19,7 @@ describe("Prompty", () => { describe("JSON serialization", () => { it("should load from JSON - example 1", () => { - const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": {\n "firstName": {\n "kind": "string",\n "default": "Jane"\n },\n "lastName": {\n "kind": "string",\n "default": "Doe"\n },\n "question": {\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n },\n "outputs": {\n "answer": {\n "kind": "string",\n "description": "The answer to the user's question."\n }\n },\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": [\n {\n "name": "getCurrentWeather",\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n ],\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some \\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to \\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; + const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": {\n "firstName": {\n "kind": "string",\n "default": "Jane"\n },\n "lastName": {\n "kind": "string",\n "default": "Doe"\n },\n "question": {\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n },\n "outputs": {\n "answer": {\n "kind": "string",\n "description": "The answer to the user's question."\n }\n },\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": [\n {\n "name": "getCurrentWeather",\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n ],\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some\\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to\\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; const instance = Prompty.fromJson(json); expect(instance).toBeDefined(); expect(instance.name).toEqual("basic-prompt"); @@ -28,12 +28,12 @@ describe("Prompty", () => { "A basic prompt that uses the GPT-3 chat API to answer questions", ); expect(instance.instructions).toEqual( - "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", + "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", ); }); it("should round-trip JSON - example 1", () => { - const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": {\n "firstName": {\n "kind": "string",\n "default": "Jane"\n },\n "lastName": {\n "kind": "string",\n "default": "Doe"\n },\n "question": {\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n },\n "outputs": {\n "answer": {\n "kind": "string",\n "description": "The answer to the user's question."\n }\n },\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": [\n {\n "name": "getCurrentWeather",\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n ],\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some \\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to \\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; + const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": {\n "firstName": {\n "kind": "string",\n "default": "Jane"\n },\n "lastName": {\n "kind": "string",\n "default": "Doe"\n },\n "question": {\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n },\n "outputs": {\n "answer": {\n "kind": "string",\n "description": "The answer to the user's question."\n }\n },\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": [\n {\n "name": "getCurrentWeather",\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n ],\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some\\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to\\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; const instance = Prompty.fromJson(json); const output = instance.toJson(); const reloaded = Prompty.fromJson(output); @@ -43,7 +43,7 @@ describe("Prompty", () => { expect(reloaded.instructions).toEqual(instance.instructions); }); it("should load from JSON - example 2", () => { - const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": {\n "firstName": {\n "kind": "string",\n "default": "Jane"\n },\n "lastName": {\n "kind": "string",\n "default": "Doe"\n },\n "question": {\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n },\n "outputs": {\n "answer": {\n "kind": "string",\n "description": "The answer to the user's question."\n }\n },\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": {\n "getCurrentWeather": {\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n },\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some \\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to \\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; + const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": {\n "firstName": {\n "kind": "string",\n "default": "Jane"\n },\n "lastName": {\n "kind": "string",\n "default": "Doe"\n },\n "question": {\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n },\n "outputs": {\n "answer": {\n "kind": "string",\n "description": "The answer to the user's question."\n }\n },\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": {\n "getCurrentWeather": {\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n },\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some\\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to\\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; const instance = Prompty.fromJson(json); expect(instance).toBeDefined(); expect(instance.name).toEqual("basic-prompt"); @@ -52,12 +52,12 @@ describe("Prompty", () => { "A basic prompt that uses the GPT-3 chat API to answer questions", ); expect(instance.instructions).toEqual( - "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", + "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", ); }); it("should round-trip JSON - example 2", () => { - const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": {\n "firstName": {\n "kind": "string",\n "default": "Jane"\n },\n "lastName": {\n "kind": "string",\n "default": "Doe"\n },\n "question": {\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n },\n "outputs": {\n "answer": {\n "kind": "string",\n "description": "The answer to the user's question."\n }\n },\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": {\n "getCurrentWeather": {\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n },\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some \\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to \\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; + const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": {\n "firstName": {\n "kind": "string",\n "default": "Jane"\n },\n "lastName": {\n "kind": "string",\n "default": "Doe"\n },\n "question": {\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n },\n "outputs": {\n "answer": {\n "kind": "string",\n "description": "The answer to the user's question."\n }\n },\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": {\n "getCurrentWeather": {\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n },\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some\\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to\\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; const instance = Prompty.fromJson(json); const output = instance.toJson(); const reloaded = Prompty.fromJson(output); @@ -67,7 +67,7 @@ describe("Prompty", () => { expect(reloaded.instructions).toEqual(instance.instructions); }); it("should load from JSON - example 3", () => { - const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": {\n "firstName": {\n "kind": "string",\n "default": "Jane"\n },\n "lastName": {\n "kind": "string",\n "default": "Doe"\n },\n "question": {\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n },\n "outputs": [\n {\n "name": "answer",\n "kind": "string",\n "description": "The answer to the user's question."\n }\n ],\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": [\n {\n "name": "getCurrentWeather",\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n ],\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some \\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to \\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; + const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": {\n "firstName": {\n "kind": "string",\n "default": "Jane"\n },\n "lastName": {\n "kind": "string",\n "default": "Doe"\n },\n "question": {\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n },\n "outputs": [\n {\n "name": "answer",\n "kind": "string",\n "description": "The answer to the user's question."\n }\n ],\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": [\n {\n "name": "getCurrentWeather",\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n ],\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some\\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to\\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; const instance = Prompty.fromJson(json); expect(instance).toBeDefined(); expect(instance.name).toEqual("basic-prompt"); @@ -76,12 +76,12 @@ describe("Prompty", () => { "A basic prompt that uses the GPT-3 chat API to answer questions", ); expect(instance.instructions).toEqual( - "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", + "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", ); }); it("should round-trip JSON - example 3", () => { - const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": {\n "firstName": {\n "kind": "string",\n "default": "Jane"\n },\n "lastName": {\n "kind": "string",\n "default": "Doe"\n },\n "question": {\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n },\n "outputs": [\n {\n "name": "answer",\n "kind": "string",\n "description": "The answer to the user's question."\n }\n ],\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": [\n {\n "name": "getCurrentWeather",\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n ],\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some \\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to \\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; + const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": {\n "firstName": {\n "kind": "string",\n "default": "Jane"\n },\n "lastName": {\n "kind": "string",\n "default": "Doe"\n },\n "question": {\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n },\n "outputs": [\n {\n "name": "answer",\n "kind": "string",\n "description": "The answer to the user's question."\n }\n ],\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": [\n {\n "name": "getCurrentWeather",\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n ],\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some\\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to\\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; const instance = Prompty.fromJson(json); const output = instance.toJson(); const reloaded = Prompty.fromJson(output); @@ -91,7 +91,7 @@ describe("Prompty", () => { expect(reloaded.instructions).toEqual(instance.instructions); }); it("should load from JSON - example 4", () => { - const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": {\n "firstName": {\n "kind": "string",\n "default": "Jane"\n },\n "lastName": {\n "kind": "string",\n "default": "Doe"\n },\n "question": {\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n },\n "outputs": [\n {\n "name": "answer",\n "kind": "string",\n "description": "The answer to the user's question."\n }\n ],\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": {\n "getCurrentWeather": {\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n },\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some \\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to \\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; + const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": {\n "firstName": {\n "kind": "string",\n "default": "Jane"\n },\n "lastName": {\n "kind": "string",\n "default": "Doe"\n },\n "question": {\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n },\n "outputs": [\n {\n "name": "answer",\n "kind": "string",\n "description": "The answer to the user's question."\n }\n ],\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": {\n "getCurrentWeather": {\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n },\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some\\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to\\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; const instance = Prompty.fromJson(json); expect(instance).toBeDefined(); expect(instance.name).toEqual("basic-prompt"); @@ -100,12 +100,12 @@ describe("Prompty", () => { "A basic prompt that uses the GPT-3 chat API to answer questions", ); expect(instance.instructions).toEqual( - "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", + "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", ); }); it("should round-trip JSON - example 4", () => { - const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": {\n "firstName": {\n "kind": "string",\n "default": "Jane"\n },\n "lastName": {\n "kind": "string",\n "default": "Doe"\n },\n "question": {\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n },\n "outputs": [\n {\n "name": "answer",\n "kind": "string",\n "description": "The answer to the user's question."\n }\n ],\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": {\n "getCurrentWeather": {\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n },\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some \\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to \\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; + const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": {\n "firstName": {\n "kind": "string",\n "default": "Jane"\n },\n "lastName": {\n "kind": "string",\n "default": "Doe"\n },\n "question": {\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n },\n "outputs": [\n {\n "name": "answer",\n "kind": "string",\n "description": "The answer to the user's question."\n }\n ],\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": {\n "getCurrentWeather": {\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n },\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some\\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to\\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; const instance = Prompty.fromJson(json); const output = instance.toJson(); const reloaded = Prompty.fromJson(output); @@ -115,7 +115,7 @@ describe("Prompty", () => { expect(reloaded.instructions).toEqual(instance.instructions); }); it("should load from JSON - example 5", () => { - const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": [\n {\n "name": "firstName",\n "kind": "string",\n "default": "Jane"\n },\n {\n "name": "lastName",\n "kind": "string",\n "default": "Doe"\n },\n {\n "name": "question",\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n ],\n "outputs": {\n "answer": {\n "kind": "string",\n "description": "The answer to the user's question."\n }\n },\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": [\n {\n "name": "getCurrentWeather",\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n ],\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some \\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to \\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; + const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": [\n {\n "name": "firstName",\n "kind": "string",\n "default": "Jane"\n },\n {\n "name": "lastName",\n "kind": "string",\n "default": "Doe"\n },\n {\n "name": "question",\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n ],\n "outputs": {\n "answer": {\n "kind": "string",\n "description": "The answer to the user's question."\n }\n },\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": [\n {\n "name": "getCurrentWeather",\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n ],\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some\\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to\\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; const instance = Prompty.fromJson(json); expect(instance).toBeDefined(); expect(instance.name).toEqual("basic-prompt"); @@ -124,12 +124,12 @@ describe("Prompty", () => { "A basic prompt that uses the GPT-3 chat API to answer questions", ); expect(instance.instructions).toEqual( - "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", + "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", ); }); it("should round-trip JSON - example 5", () => { - const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": [\n {\n "name": "firstName",\n "kind": "string",\n "default": "Jane"\n },\n {\n "name": "lastName",\n "kind": "string",\n "default": "Doe"\n },\n {\n "name": "question",\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n ],\n "outputs": {\n "answer": {\n "kind": "string",\n "description": "The answer to the user's question."\n }\n },\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": [\n {\n "name": "getCurrentWeather",\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n ],\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some \\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to \\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; + const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": [\n {\n "name": "firstName",\n "kind": "string",\n "default": "Jane"\n },\n {\n "name": "lastName",\n "kind": "string",\n "default": "Doe"\n },\n {\n "name": "question",\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n ],\n "outputs": {\n "answer": {\n "kind": "string",\n "description": "The answer to the user's question."\n }\n },\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": [\n {\n "name": "getCurrentWeather",\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n ],\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some\\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to\\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; const instance = Prompty.fromJson(json); const output = instance.toJson(); const reloaded = Prompty.fromJson(output); @@ -139,7 +139,7 @@ describe("Prompty", () => { expect(reloaded.instructions).toEqual(instance.instructions); }); it("should load from JSON - example 6", () => { - const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": [\n {\n "name": "firstName",\n "kind": "string",\n "default": "Jane"\n },\n {\n "name": "lastName",\n "kind": "string",\n "default": "Doe"\n },\n {\n "name": "question",\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n ],\n "outputs": {\n "answer": {\n "kind": "string",\n "description": "The answer to the user's question."\n }\n },\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": {\n "getCurrentWeather": {\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n },\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some \\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to \\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; + const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": [\n {\n "name": "firstName",\n "kind": "string",\n "default": "Jane"\n },\n {\n "name": "lastName",\n "kind": "string",\n "default": "Doe"\n },\n {\n "name": "question",\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n ],\n "outputs": {\n "answer": {\n "kind": "string",\n "description": "The answer to the user's question."\n }\n },\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": {\n "getCurrentWeather": {\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n },\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some\\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to\\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; const instance = Prompty.fromJson(json); expect(instance).toBeDefined(); expect(instance.name).toEqual("basic-prompt"); @@ -148,12 +148,12 @@ describe("Prompty", () => { "A basic prompt that uses the GPT-3 chat API to answer questions", ); expect(instance.instructions).toEqual( - "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", + "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", ); }); it("should round-trip JSON - example 6", () => { - const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": [\n {\n "name": "firstName",\n "kind": "string",\n "default": "Jane"\n },\n {\n "name": "lastName",\n "kind": "string",\n "default": "Doe"\n },\n {\n "name": "question",\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n ],\n "outputs": {\n "answer": {\n "kind": "string",\n "description": "The answer to the user's question."\n }\n },\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": {\n "getCurrentWeather": {\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n },\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some \\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to \\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; + const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": [\n {\n "name": "firstName",\n "kind": "string",\n "default": "Jane"\n },\n {\n "name": "lastName",\n "kind": "string",\n "default": "Doe"\n },\n {\n "name": "question",\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n ],\n "outputs": {\n "answer": {\n "kind": "string",\n "description": "The answer to the user's question."\n }\n },\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": {\n "getCurrentWeather": {\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n },\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some\\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to\\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; const instance = Prompty.fromJson(json); const output = instance.toJson(); const reloaded = Prompty.fromJson(output); @@ -163,7 +163,7 @@ describe("Prompty", () => { expect(reloaded.instructions).toEqual(instance.instructions); }); it("should load from JSON - example 7", () => { - const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": [\n {\n "name": "firstName",\n "kind": "string",\n "default": "Jane"\n },\n {\n "name": "lastName",\n "kind": "string",\n "default": "Doe"\n },\n {\n "name": "question",\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n ],\n "outputs": [\n {\n "name": "answer",\n "kind": "string",\n "description": "The answer to the user's question."\n }\n ],\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": [\n {\n "name": "getCurrentWeather",\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n ],\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some \\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to \\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; + const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": [\n {\n "name": "firstName",\n "kind": "string",\n "default": "Jane"\n },\n {\n "name": "lastName",\n "kind": "string",\n "default": "Doe"\n },\n {\n "name": "question",\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n ],\n "outputs": [\n {\n "name": "answer",\n "kind": "string",\n "description": "The answer to the user's question."\n }\n ],\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": [\n {\n "name": "getCurrentWeather",\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n ],\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some\\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to\\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; const instance = Prompty.fromJson(json); expect(instance).toBeDefined(); expect(instance.name).toEqual("basic-prompt"); @@ -172,12 +172,12 @@ describe("Prompty", () => { "A basic prompt that uses the GPT-3 chat API to answer questions", ); expect(instance.instructions).toEqual( - "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", + "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", ); }); it("should round-trip JSON - example 7", () => { - const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": [\n {\n "name": "firstName",\n "kind": "string",\n "default": "Jane"\n },\n {\n "name": "lastName",\n "kind": "string",\n "default": "Doe"\n },\n {\n "name": "question",\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n ],\n "outputs": [\n {\n "name": "answer",\n "kind": "string",\n "description": "The answer to the user's question."\n }\n ],\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": [\n {\n "name": "getCurrentWeather",\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n ],\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some \\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to \\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; + const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": [\n {\n "name": "firstName",\n "kind": "string",\n "default": "Jane"\n },\n {\n "name": "lastName",\n "kind": "string",\n "default": "Doe"\n },\n {\n "name": "question",\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n ],\n "outputs": [\n {\n "name": "answer",\n "kind": "string",\n "description": "The answer to the user's question."\n }\n ],\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": [\n {\n "name": "getCurrentWeather",\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n ],\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some\\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to\\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; const instance = Prompty.fromJson(json); const output = instance.toJson(); const reloaded = Prompty.fromJson(output); @@ -187,7 +187,7 @@ describe("Prompty", () => { expect(reloaded.instructions).toEqual(instance.instructions); }); it("should load from JSON - example 8", () => { - const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": [\n {\n "name": "firstName",\n "kind": "string",\n "default": "Jane"\n },\n {\n "name": "lastName",\n "kind": "string",\n "default": "Doe"\n },\n {\n "name": "question",\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n ],\n "outputs": [\n {\n "name": "answer",\n "kind": "string",\n "description": "The answer to the user's question."\n }\n ],\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": {\n "getCurrentWeather": {\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n },\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some \\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to \\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; + const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": [\n {\n "name": "firstName",\n "kind": "string",\n "default": "Jane"\n },\n {\n "name": "lastName",\n "kind": "string",\n "default": "Doe"\n },\n {\n "name": "question",\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n ],\n "outputs": [\n {\n "name": "answer",\n "kind": "string",\n "description": "The answer to the user's question."\n }\n ],\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": {\n "getCurrentWeather": {\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n },\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some\\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to\\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; const instance = Prompty.fromJson(json); expect(instance).toBeDefined(); expect(instance.name).toEqual("basic-prompt"); @@ -196,12 +196,12 @@ describe("Prompty", () => { "A basic prompt that uses the GPT-3 chat API to answer questions", ); expect(instance.instructions).toEqual( - "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", + "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", ); }); it("should round-trip JSON - example 8", () => { - const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": [\n {\n "name": "firstName",\n "kind": "string",\n "default": "Jane"\n },\n {\n "name": "lastName",\n "kind": "string",\n "default": "Doe"\n },\n {\n "name": "question",\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n ],\n "outputs": [\n {\n "name": "answer",\n "kind": "string",\n "description": "The answer to the user's question."\n }\n ],\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": {\n "getCurrentWeather": {\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n },\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some \\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to \\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; + const json = `{\n "name": "basic-prompt",\n "displayName": "Basic Prompt",\n "description": "A basic prompt that uses the GPT-3 chat API to answer questions",\n "metadata": {\n "authors": [\n "sethjuarez",\n "jietong"\n ],\n "tags": [\n "example",\n "prompt"\n ]\n },\n "inputs": [\n {\n "name": "firstName",\n "kind": "string",\n "default": "Jane"\n },\n {\n "name": "lastName",\n "kind": "string",\n "default": "Doe"\n },\n {\n "name": "question",\n "kind": "string",\n "default": "What is the meaning of life?"\n }\n ],\n "outputs": [\n {\n "name": "answer",\n "kind": "string",\n "description": "The answer to the user's question."\n }\n ],\n "model": {\n "id": "gpt-35-turbo",\n "connection": {\n "kind": "key",\n "endpoint": "https://{your-custom-endpoint}.openai.azure.com/",\n "apiKey": "{your-api-key}"\n }\n },\n "tools": {\n "getCurrentWeather": {\n "kind": "function",\n "description": "Get the current weather in a given location",\n "parameters": {\n "location": {\n "kind": "string",\n "description": "The city and state, e.g. San Francisco, CA"\n },\n "unit": {\n "kind": "string",\n "description": "The unit of temperature, e.g. Celsius or Fahrenheit"\n }\n }\n }\n },\n "template": {\n "format": "mustache",\n "parser": "prompty"\n },\n "instructions": "system:\\nYou are an AI assistant who helps people find information.\\nAs the assistant, you answer questions briefly, succinctly,\\nand in a personable manner using markdown and even add some\\npersonal flair with appropriate emojis.\\n\\n# Customer\\nYou are helping {{firstName}} {{lastName}} to find answers to\\ntheir questions. Use their name to address them in your responses.\\nuser:\\n{{question}}"\n}`; const instance = Prompty.fromJson(json); const output = instance.toJson(); const reloaded = Prompty.fromJson(output); @@ -214,7 +214,7 @@ describe("Prompty", () => { describe("YAML serialization", () => { it("should load from YAML - example 1", () => { - const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n firstName:\n kind: string\n default: Jane\n lastName:\n kind: string\n default: Doe\n question:\n kind: string\n default: What is the meaning of life?\noutputs:\n answer:\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n - name: getCurrentWeather\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\\ \n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\\ \n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; + const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n firstName:\n kind: string\n default: Jane\n lastName:\n kind: string\n default: Doe\n question:\n kind: string\n default: What is the meaning of life?\noutputs:\n answer:\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n - name: getCurrentWeather\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; const instance = Prompty.fromYaml(yaml); expect(instance).toBeDefined(); expect(instance.name).toEqual("basic-prompt"); @@ -223,12 +223,12 @@ describe("Prompty", () => { "A basic prompt that uses the GPT-3 chat API to answer questions", ); expect(instance.instructions).toEqual( - "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", + "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", ); }); it("should round-trip YAML - example 1", () => { - const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n firstName:\n kind: string\n default: Jane\n lastName:\n kind: string\n default: Doe\n question:\n kind: string\n default: What is the meaning of life?\noutputs:\n answer:\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n - name: getCurrentWeather\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\\ \n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\\ \n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; + const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n firstName:\n kind: string\n default: Jane\n lastName:\n kind: string\n default: Doe\n question:\n kind: string\n default: What is the meaning of life?\noutputs:\n answer:\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n - name: getCurrentWeather\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; const instance = Prompty.fromYaml(yaml); const output = instance.toYaml(); const reloaded = Prompty.fromYaml(output); @@ -238,7 +238,7 @@ describe("Prompty", () => { expect(reloaded.instructions).toEqual(instance.instructions); }); it("should load from YAML - example 2", () => { - const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n firstName:\n kind: string\n default: Jane\n lastName:\n kind: string\n default: Doe\n question:\n kind: string\n default: What is the meaning of life?\noutputs:\n answer:\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n getCurrentWeather:\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\\ \n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\\ \n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; + const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n firstName:\n kind: string\n default: Jane\n lastName:\n kind: string\n default: Doe\n question:\n kind: string\n default: What is the meaning of life?\noutputs:\n answer:\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n getCurrentWeather:\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; const instance = Prompty.fromYaml(yaml); expect(instance).toBeDefined(); expect(instance.name).toEqual("basic-prompt"); @@ -247,12 +247,12 @@ describe("Prompty", () => { "A basic prompt that uses the GPT-3 chat API to answer questions", ); expect(instance.instructions).toEqual( - "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", + "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", ); }); it("should round-trip YAML - example 2", () => { - const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n firstName:\n kind: string\n default: Jane\n lastName:\n kind: string\n default: Doe\n question:\n kind: string\n default: What is the meaning of life?\noutputs:\n answer:\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n getCurrentWeather:\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\\ \n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\\ \n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; + const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n firstName:\n kind: string\n default: Jane\n lastName:\n kind: string\n default: Doe\n question:\n kind: string\n default: What is the meaning of life?\noutputs:\n answer:\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n getCurrentWeather:\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; const instance = Prompty.fromYaml(yaml); const output = instance.toYaml(); const reloaded = Prompty.fromYaml(output); @@ -262,7 +262,7 @@ describe("Prompty", () => { expect(reloaded.instructions).toEqual(instance.instructions); }); it("should load from YAML - example 3", () => { - const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n firstName:\n kind: string\n default: Jane\n lastName:\n kind: string\n default: Doe\n question:\n kind: string\n default: What is the meaning of life?\noutputs:\n - name: answer\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n - name: getCurrentWeather\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\\ \n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\\ \n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; + const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n firstName:\n kind: string\n default: Jane\n lastName:\n kind: string\n default: Doe\n question:\n kind: string\n default: What is the meaning of life?\noutputs:\n - name: answer\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n - name: getCurrentWeather\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; const instance = Prompty.fromYaml(yaml); expect(instance).toBeDefined(); expect(instance.name).toEqual("basic-prompt"); @@ -271,12 +271,12 @@ describe("Prompty", () => { "A basic prompt that uses the GPT-3 chat API to answer questions", ); expect(instance.instructions).toEqual( - "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", + "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", ); }); it("should round-trip YAML - example 3", () => { - const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n firstName:\n kind: string\n default: Jane\n lastName:\n kind: string\n default: Doe\n question:\n kind: string\n default: What is the meaning of life?\noutputs:\n - name: answer\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n - name: getCurrentWeather\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\\ \n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\\ \n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; + const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n firstName:\n kind: string\n default: Jane\n lastName:\n kind: string\n default: Doe\n question:\n kind: string\n default: What is the meaning of life?\noutputs:\n - name: answer\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n - name: getCurrentWeather\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; const instance = Prompty.fromYaml(yaml); const output = instance.toYaml(); const reloaded = Prompty.fromYaml(output); @@ -286,7 +286,7 @@ describe("Prompty", () => { expect(reloaded.instructions).toEqual(instance.instructions); }); it("should load from YAML - example 4", () => { - const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n firstName:\n kind: string\n default: Jane\n lastName:\n kind: string\n default: Doe\n question:\n kind: string\n default: What is the meaning of life?\noutputs:\n - name: answer\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n getCurrentWeather:\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\\ \n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\\ \n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; + const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n firstName:\n kind: string\n default: Jane\n lastName:\n kind: string\n default: Doe\n question:\n kind: string\n default: What is the meaning of life?\noutputs:\n - name: answer\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n getCurrentWeather:\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; const instance = Prompty.fromYaml(yaml); expect(instance).toBeDefined(); expect(instance.name).toEqual("basic-prompt"); @@ -295,12 +295,12 @@ describe("Prompty", () => { "A basic prompt that uses the GPT-3 chat API to answer questions", ); expect(instance.instructions).toEqual( - "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", + "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", ); }); it("should round-trip YAML - example 4", () => { - const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n firstName:\n kind: string\n default: Jane\n lastName:\n kind: string\n default: Doe\n question:\n kind: string\n default: What is the meaning of life?\noutputs:\n - name: answer\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n getCurrentWeather:\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\\ \n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\\ \n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; + const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n firstName:\n kind: string\n default: Jane\n lastName:\n kind: string\n default: Doe\n question:\n kind: string\n default: What is the meaning of life?\noutputs:\n - name: answer\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n getCurrentWeather:\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; const instance = Prompty.fromYaml(yaml); const output = instance.toYaml(); const reloaded = Prompty.fromYaml(output); @@ -310,7 +310,7 @@ describe("Prompty", () => { expect(reloaded.instructions).toEqual(instance.instructions); }); it("should load from YAML - example 5", () => { - const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n - name: firstName\n kind: string\n default: Jane\n - name: lastName\n kind: string\n default: Doe\n - name: question\n kind: string\n default: What is the meaning of life?\noutputs:\n answer:\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n - name: getCurrentWeather\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\\ \n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\\ \n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; + const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n - name: firstName\n kind: string\n default: Jane\n - name: lastName\n kind: string\n default: Doe\n - name: question\n kind: string\n default: What is the meaning of life?\noutputs:\n answer:\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n - name: getCurrentWeather\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; const instance = Prompty.fromYaml(yaml); expect(instance).toBeDefined(); expect(instance.name).toEqual("basic-prompt"); @@ -319,12 +319,12 @@ describe("Prompty", () => { "A basic prompt that uses the GPT-3 chat API to answer questions", ); expect(instance.instructions).toEqual( - "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", + "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", ); }); it("should round-trip YAML - example 5", () => { - const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n - name: firstName\n kind: string\n default: Jane\n - name: lastName\n kind: string\n default: Doe\n - name: question\n kind: string\n default: What is the meaning of life?\noutputs:\n answer:\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n - name: getCurrentWeather\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\\ \n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\\ \n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; + const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n - name: firstName\n kind: string\n default: Jane\n - name: lastName\n kind: string\n default: Doe\n - name: question\n kind: string\n default: What is the meaning of life?\noutputs:\n answer:\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n - name: getCurrentWeather\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; const instance = Prompty.fromYaml(yaml); const output = instance.toYaml(); const reloaded = Prompty.fromYaml(output); @@ -334,7 +334,7 @@ describe("Prompty", () => { expect(reloaded.instructions).toEqual(instance.instructions); }); it("should load from YAML - example 6", () => { - const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n - name: firstName\n kind: string\n default: Jane\n - name: lastName\n kind: string\n default: Doe\n - name: question\n kind: string\n default: What is the meaning of life?\noutputs:\n answer:\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n getCurrentWeather:\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\\ \n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\\ \n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; + const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n - name: firstName\n kind: string\n default: Jane\n - name: lastName\n kind: string\n default: Doe\n - name: question\n kind: string\n default: What is the meaning of life?\noutputs:\n answer:\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n getCurrentWeather:\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; const instance = Prompty.fromYaml(yaml); expect(instance).toBeDefined(); expect(instance.name).toEqual("basic-prompt"); @@ -343,12 +343,12 @@ describe("Prompty", () => { "A basic prompt that uses the GPT-3 chat API to answer questions", ); expect(instance.instructions).toEqual( - "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", + "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", ); }); it("should round-trip YAML - example 6", () => { - const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n - name: firstName\n kind: string\n default: Jane\n - name: lastName\n kind: string\n default: Doe\n - name: question\n kind: string\n default: What is the meaning of life?\noutputs:\n answer:\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n getCurrentWeather:\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\\ \n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\\ \n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; + const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n - name: firstName\n kind: string\n default: Jane\n - name: lastName\n kind: string\n default: Doe\n - name: question\n kind: string\n default: What is the meaning of life?\noutputs:\n answer:\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n getCurrentWeather:\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; const instance = Prompty.fromYaml(yaml); const output = instance.toYaml(); const reloaded = Prompty.fromYaml(output); @@ -358,7 +358,7 @@ describe("Prompty", () => { expect(reloaded.instructions).toEqual(instance.instructions); }); it("should load from YAML - example 7", () => { - const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n - name: firstName\n kind: string\n default: Jane\n - name: lastName\n kind: string\n default: Doe\n - name: question\n kind: string\n default: What is the meaning of life?\noutputs:\n - name: answer\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n - name: getCurrentWeather\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\\ \n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\\ \n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; + const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n - name: firstName\n kind: string\n default: Jane\n - name: lastName\n kind: string\n default: Doe\n - name: question\n kind: string\n default: What is the meaning of life?\noutputs:\n - name: answer\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n - name: getCurrentWeather\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; const instance = Prompty.fromYaml(yaml); expect(instance).toBeDefined(); expect(instance.name).toEqual("basic-prompt"); @@ -367,12 +367,12 @@ describe("Prompty", () => { "A basic prompt that uses the GPT-3 chat API to answer questions", ); expect(instance.instructions).toEqual( - "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", + "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", ); }); it("should round-trip YAML - example 7", () => { - const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n - name: firstName\n kind: string\n default: Jane\n - name: lastName\n kind: string\n default: Doe\n - name: question\n kind: string\n default: What is the meaning of life?\noutputs:\n - name: answer\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n - name: getCurrentWeather\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\\ \n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\\ \n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; + const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n - name: firstName\n kind: string\n default: Jane\n - name: lastName\n kind: string\n default: Doe\n - name: question\n kind: string\n default: What is the meaning of life?\noutputs:\n - name: answer\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n - name: getCurrentWeather\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; const instance = Prompty.fromYaml(yaml); const output = instance.toYaml(); const reloaded = Prompty.fromYaml(output); @@ -382,7 +382,7 @@ describe("Prompty", () => { expect(reloaded.instructions).toEqual(instance.instructions); }); it("should load from YAML - example 8", () => { - const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n - name: firstName\n kind: string\n default: Jane\n - name: lastName\n kind: string\n default: Doe\n - name: question\n kind: string\n default: What is the meaning of life?\noutputs:\n - name: answer\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n getCurrentWeather:\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\\ \n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\\ \n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; + const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n - name: firstName\n kind: string\n default: Jane\n - name: lastName\n kind: string\n default: Doe\n - name: question\n kind: string\n default: What is the meaning of life?\noutputs:\n - name: answer\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n getCurrentWeather:\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; const instance = Prompty.fromYaml(yaml); expect(instance).toBeDefined(); expect(instance.name).toEqual("basic-prompt"); @@ -391,12 +391,12 @@ describe("Prompty", () => { "A basic prompt that uses the GPT-3 chat API to answer questions", ); expect(instance.instructions).toEqual( - "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", + "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}", ); }); it("should round-trip YAML - example 8", () => { - const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n - name: firstName\n kind: string\n default: Jane\n - name: lastName\n kind: string\n default: Doe\n - name: question\n kind: string\n default: What is the meaning of life?\noutputs:\n - name: answer\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n getCurrentWeather:\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\\ \n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\\ \n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; + const yaml = `name: basic-prompt\ndisplayName: Basic Prompt\ndescription: A basic prompt that uses the GPT-3 chat API to answer questions\nmetadata:\n authors:\n - sethjuarez\n - jietong\n tags:\n - example\n - prompt\ninputs:\n - name: firstName\n kind: string\n default: Jane\n - name: lastName\n kind: string\n default: Doe\n - name: question\n kind: string\n default: What is the meaning of life?\noutputs:\n - name: answer\n kind: string\n description: The answer to the user's question.\nmodel:\n id: gpt-35-turbo\n connection:\n kind: key\n endpoint: "https://{your-custom-endpoint}.openai.azure.com/"\n apiKey: "{your-api-key}"\ntools:\n getCurrentWeather:\n kind: function\n description: Get the current weather in a given location\n parameters:\n location:\n kind: string\n description: The city and state, e.g. San Francisco, CA\n unit:\n kind: string\n description: The unit of temperature, e.g. Celsius or Fahrenheit\ntemplate:\n format: mustache\n parser: prompty\ninstructions: "system:\n\n You are an AI assistant who helps people find information.\n\n As the assistant, you answer questions briefly, succinctly,\n\n and in a personable manner using markdown and even add some\n\n personal flair with appropriate emojis.\n\n\n # Customer\n\n You are helping {{firstName}} {{lastName}} to find answers to\n\n their questions. Use their name to address them in your responses.\n\n user:\n\n {{question}}"\n`; const instance = Prompty.fromYaml(yaml); const output = instance.toYaml(); const reloaded = Prompty.fromYaml(output); diff --git a/schema/model/agent/agent.tsp b/schema/model/agent/agent.tsp index 0a7094e12..a1d7e7536 100644 --- a/schema/model/agent/agent.tsp +++ b/schema/model/agent/agent.tsp @@ -163,11 +163,11 @@ model Prompty { system: You are an AI assistant who helps people find information. As the assistant, you answer questions briefly, succinctly, - and in a personable manner using markdown and even add some + and in a personable manner using markdown and even add some personal flair with appropriate emojis. # Customer - You are helping {{firstName}} {{lastName}} to find answers to + You are helping {{firstName}} {{lastName}} to find answers to their questions. Use their name to address them in your responses. user: {{question}} diff --git a/schema/tsp-output/json-ast/model.json b/schema/tsp-output/json-ast/model.json index a67546c6f..62b2d49af 100644 --- a/schema/tsp-output/json-ast/model.json +++ b/schema/tsp-output/json-ast/model.json @@ -6292,7 +6292,7 @@ "samples": [ { "sample": { - "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some \npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to \ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" + "instructions": "system:\nYou are an AI assistant who helps people find information.\nAs the assistant, you answer questions briefly, succinctly,\nand in a personable manner using markdown and even add some\npersonal flair with appropriate emojis.\n\n# Customer\nYou are helping {{firstName}} {{lastName}} to find answers to\ntheir questions. Use their name to address them in your responses.\nuser:\n{{question}}" }, "title": "", "description": "" From 2f98bec9d0de2f4df906b3d6acc5a5db7fa1a114 Mon Sep 17 00:00:00 2001 From: Seth Juarez Date: Tue, 4 Aug 2026 02:04:05 -0700 Subject: [PATCH 07/10] fix(python): restore runtime CI checks Apply the configured Ruff formatting and assert the nullable strict-output wire shape already produced for optional fields. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- runtime/python/prompty/README.md | 34 ++++++------------- .../prompty/providers/openai/executor.py | 8 ++--- .../python/prompty/tests/test_responses.py | 2 +- 3 files changed, 14 insertions(+), 30 deletions(-) diff --git a/runtime/python/prompty/README.md b/runtime/python/prompty/README.md index a4e1729e1..985e8b017 100644 --- a/runtime/python/prompty/README.md +++ b/runtime/python/prompty/README.md @@ -72,25 +72,19 @@ Say hello to {{name}}. import prompty # One-shot: load + prepare + run -result = prompty.invoke( - "greeting.prompty", inputs={"name": "Jane"} -) +result = prompty.invoke("greeting.prompty", inputs={"name": "Jane"}) print(result) # Step-by-step agent = prompty.load("greeting.prompty") -messages = prompty.prepare( - agent, inputs={"name": "Jane"} -) +messages = prompty.prepare(agent, inputs={"name": "Jane"}) result = prompty.run(agent, messages) ``` ### 3. Async ```python -result = await prompty.invoke_async( - "greeting.prompty", inputs={"name": "Jane"} -) +result = await prompty.invoke_async("greeting.prompty", inputs={"name": "Jane"}) ``` ## API Reference @@ -118,6 +112,7 @@ All functions have `_async` variants (e.g., def get_weather(location: str) -> str: return f"72°F and sunny in {location}" + result = prompty.turn( "my-agent.prompty", inputs={"question": "Weather in Seattle?"}, @@ -170,9 +165,7 @@ client = AzureOpenAI( prompty.register_connection("my-foundry", client=client) # Now run — executor resolves the client by name -result = prompty.invoke( - "my-prompt.prompty", inputs={...} -) +result = prompty.invoke("my-prompt.prompty", inputs={...}) ``` ### Structured Output @@ -198,9 +191,7 @@ JSON-parses the result. ```python agent = prompty.load("chat.prompty") -messages = prompty.prepare( - agent, inputs={"question": "Tell me a story"} -) +messages = prompty.prepare(agent, inputs={"question": "Tell me a story"}) # Set stream option agent.model.options.additionalProperties = { @@ -224,25 +215,22 @@ from prompty import Tracer, PromptyTracer, trace # Register a tracer Tracer.add("console", prompty.console_tracer) -Tracer.add( - "json", PromptyTracer("./traces").tracer -) +Tracer.add("json", PromptyTracer("./traces").tracer) # All pipeline functions automatically emit traces -result = prompty.invoke( - "my-prompt.prompty", inputs={...} -) +result = prompty.invoke("my-prompt.prompty", inputs={...}) + # Custom functions @trace -def my_function(): - ... +def my_function(): ... ``` OpenTelemetry integration: ```python from prompty.tracing.otel import otel_tracer + Tracer.add("otel", otel_tracer()) ``` diff --git a/runtime/python/prompty/prompty/providers/openai/executor.py b/runtime/python/prompty/prompty/providers/openai/executor.py index 7aa263692..e777e331f 100644 --- a/runtime/python/prompty/prompty/providers/openai/executor.py +++ b/runtime/python/prompty/prompty/providers/openai/executor.py @@ -223,9 +223,7 @@ def _property_to_json_schema(prop: Any, *, optional: bool = False, strict: bool props: dict[str, Any] = {} required: list[str] = [] for p in prop.properties: - props[p.name] = _property_to_json_schema( - p, optional=strict and not bool(p.required), strict=strict - ) + props[p.name] = _property_to_json_schema(p, optional=strict and not bool(p.required), strict=strict) if strict or p.required: required.append(p.name) schema["properties"] = props @@ -366,9 +364,7 @@ def _responses_tools_to_wire(agent: Prompty) -> list[dict[str, Any]] | None: if tool.description: tool_def["description"] = tool.description if hasattr(tool, "parameters") and tool.parameters: - tool_def["parameters"] = _schema_to_wire( - tool.parameters, strict=bool(getattr(tool, "strict", False)) - ) + tool_def["parameters"] = _schema_to_wire(tool.parameters, strict=bool(getattr(tool, "strict", False))) if hasattr(tool, "strict") and tool.strict: tool_def["strict"] = True if "parameters" in tool_def: diff --git a/runtime/python/prompty/tests/test_responses.py b/runtime/python/prompty/tests/test_responses.py index 86fd8e3c5..23f6c942f 100644 --- a/runtime/python/prompty/tests/test_responses.py +++ b/runtime/python/prompty/tests/test_responses.py @@ -231,7 +231,7 @@ def test_basic_schema(self) -> None: assert schema["type"] == "object" assert "temperature" in schema["properties"] assert "condition" in schema["properties"] - assert schema["properties"]["temperature"]["type"] == "integer" + assert schema["properties"]["temperature"]["type"] == ["integer", "null"] assert schema["additionalProperties"] is False From 242e27f34ccebc27b15a86c949cd670e03a5d701 Mon Sep 17 00:00:00 2001 From: Seth Juarez Date: Tue, 4 Aug 2026 02:48:27 -0700 Subject: [PATCH 08/10] test(schema): generate failure chunk round trips Add a canonical nested failure sample so Typra emits load/save and JSON/YAML conversion coverage for FailureChunk across configured runtimes. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../events/FailureChunkConversionTests.cs | 113 +++++++++ .../go/prompty/model/failure_chunk_test.go | 240 ++++++++++++++++++ .../tests/model/events/test_failure_chunk.py | 85 +++++++ .../tests/model/events/failure-chunk.test.ts | 30 +++ schema/model/events/stream-chunks.tsp | 6 + .../tsp-output/.typra-generated/manifest.json | 5 + .../content/docs/reference/FailureChunk.md | 8 + 7 files changed, 487 insertions(+) create mode 100644 runtime/python/prompty/tests/model/events/test_failure_chunk.py diff --git a/runtime/csharp/Prompty.Core.Tests/Model/events/FailureChunkConversionTests.cs b/runtime/csharp/Prompty.Core.Tests/Model/events/FailureChunkConversionTests.cs index ff7ebd431..66f9fb113 100644 --- a/runtime/csharp/Prompty.Core.Tests/Model/events/FailureChunkConversionTests.cs +++ b/runtime/csharp/Prompty.Core.Tests/Model/events/FailureChunkConversionTests.cs @@ -8,4 +8,117 @@ namespace Prompty.Core; public class FailureChunkConversionTests { + [Fact] + public void LoadYamlInput() + { + string yamlData = """ +failure: + outcome: indeterminate + message: "SSE stream error: connection reset" + +"""; + + var instance = FailureChunk.FromYaml(yamlData); + + Assert.NotNull(instance); + } + + [Fact] + public void LoadJsonInput() + { + string jsonData = """ +{ + "failure": { + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" + } +} +"""; + + var instance = FailureChunk.FromJson(jsonData); + Assert.NotNull(instance); + } + + [Fact] + public void RoundtripJson() + { + // Test that FromJson -> ToJson -> FromJson produces equivalent data + string jsonData = """ +{ + "failure": { + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" + } +} +"""; + + var original = FailureChunk.FromJson(jsonData); + Assert.NotNull(original); + + var json = original.ToJson(); + Assert.False(string.IsNullOrEmpty(json)); + + var reloaded = FailureChunk.FromJson(json); + Assert.NotNull(reloaded); + } + + [Fact] + public void RoundtripYaml() + { + // Test that FromYaml -> ToYaml -> FromYaml produces equivalent data + string yamlData = """ +failure: + outcome: indeterminate + message: "SSE stream error: connection reset" + +"""; + + var original = FailureChunk.FromYaml(yamlData); + Assert.NotNull(original); + + var yaml = original.ToYaml(); + Assert.False(string.IsNullOrEmpty(yaml)); + + var reloaded = FailureChunk.FromYaml(yaml); + Assert.NotNull(reloaded); + } + + [Fact] + public void ToJsonProducesValidJson() + { + string jsonData = """ +{ + "failure": { + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" + } +} +"""; + + var instance = FailureChunk.FromJson(jsonData); + var json = instance.ToJson(); + + // Verify it's valid JSON by parsing it + var parsed = System.Text.Json.JsonDocument.Parse(json); + Assert.NotNull(parsed); + } + + [Fact] + public void ToYamlProducesValidYaml() + { + string yamlData = """ +failure: + outcome: indeterminate + message: "SSE stream error: connection reset" + +"""; + + var instance = FailureChunk.FromYaml(yamlData); + var yaml = instance.ToYaml(); + + // Verify it's valid YAML by parsing it + var deserializer = new YamlDotNet.Serialization.DeserializerBuilder().Build(); + var parsed = deserializer.Deserialize(yaml); + Assert.NotNull(parsed); + } } diff --git a/runtime/go/prompty/model/failure_chunk_test.go b/runtime/go/prompty/model/failure_chunk_test.go index 9cc5440c4..0a7338f1b 100644 --- a/runtime/go/prompty/model/failure_chunk_test.go +++ b/runtime/go/prompty/model/failure_chunk_test.go @@ -2,3 +2,243 @@ // Code generated by Typra emitter; DO NOT EDIT. package prompty_test + +import ( + "encoding/json" + "testing" + + "gopkg.in/yaml.v3" + + "prompty/model" +) + +// TestFailureChunkLoadJSON tests loading FailureChunk from JSON +func TestFailureChunkLoadJSON(t *testing.T) { + jsonData := ` +{ + "failure": { + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" + } +} +` + var data map[string]interface{} + if err := json.Unmarshal([]byte(jsonData), &data); err != nil { + t.Fatalf("Failed to parse JSON: %v", err) + } + + ctx := prompty.NewLoadContext() + instance, err := prompty.LoadFailureChunk(data, ctx) + if err != nil { + t.Fatalf("Failed to load FailureChunk: %v", err) + } + _ = instance // No scalar properties to validate + if instance.Failure.Outcome != "indeterminate" { + t.Errorf(`Expected Failure.Outcome to be "indeterminate", got %v`, instance.Failure.Outcome) + } + if instance.Failure.Message != "SSE stream error: connection reset" { + t.Errorf(`Expected Failure.Message to be "SSE stream error: connection reset", got %v`, instance.Failure.Message) + } +} + +// TestFailureChunkLoadYAML tests loading FailureChunk from YAML +func TestFailureChunkLoadYAML(t *testing.T) { + yamlData := ` +failure: + outcome: indeterminate + message: "SSE stream error: connection reset" + +` + var data map[string]interface{} + if err := yaml.Unmarshal([]byte(yamlData), &data); err != nil { + t.Fatalf("Failed to parse YAML: %v", err) + } + + ctx := prompty.NewLoadContext() + instance, err := prompty.LoadFailureChunk(data, ctx) + if err != nil { + t.Fatalf("Failed to load FailureChunk: %v", err) + } + _ = instance // No scalar properties to validate + if instance.Failure.Outcome != "indeterminate" { + t.Errorf(`Expected Failure.Outcome to be "indeterminate", got %v`, instance.Failure.Outcome) + } + if instance.Failure.Message != "SSE stream error: connection reset" { + t.Errorf(`Expected Failure.Message to be "SSE stream error: connection reset", got %v`, instance.Failure.Message) + } +} + +// TestFailureChunkFromJSON tests loading FailureChunk through the generated JSON helper +func TestFailureChunkFromJSON(t *testing.T) { + jsonData := ` +{ + "failure": { + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" + } +} +` + + instance, err := prompty.FailureChunkFromJSON(jsonData) + if err != nil { + t.Fatalf("Failed to load FailureChunk from JSON helper: %v", err) + } + _ = instance // No scalar properties to validate + if instance.Failure.Outcome != "indeterminate" { + t.Errorf(`Expected Failure.Outcome to be "indeterminate", got %v`, instance.Failure.Outcome) + } + if instance.Failure.Message != "SSE stream error: connection reset" { + t.Errorf(`Expected Failure.Message to be "SSE stream error: connection reset", got %v`, instance.Failure.Message) + } +} + +// TestFailureChunkFromYAML tests loading FailureChunk through the generated YAML helper +func TestFailureChunkFromYAML(t *testing.T) { + yamlData := ` +failure: + outcome: indeterminate + message: "SSE stream error: connection reset" + +` + + instance, err := prompty.FailureChunkFromYAML(yamlData) + if err != nil { + t.Fatalf("Failed to load FailureChunk from YAML helper: %v", err) + } + _ = instance // No scalar properties to validate + if instance.Failure.Outcome != "indeterminate" { + t.Errorf(`Expected Failure.Outcome to be "indeterminate", got %v`, instance.Failure.Outcome) + } + if instance.Failure.Message != "SSE stream error: connection reset" { + t.Errorf(`Expected Failure.Message to be "SSE stream error: connection reset", got %v`, instance.Failure.Message) + } +} + +// TestFailureChunkRoundtrip tests load -> save -> load produces equivalent data +func TestFailureChunkRoundtrip(t *testing.T) { + jsonData := ` +{ + "failure": { + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" + } +} +` + var data map[string]interface{} + if err := json.Unmarshal([]byte(jsonData), &data); err != nil { + t.Fatalf("Failed to parse JSON: %v", err) + } + + loadCtx := prompty.NewLoadContext() + instance, err := prompty.LoadFailureChunk(data, loadCtx) + if err != nil { + t.Fatalf("Failed to load FailureChunk: %v", err) + } + saveCtx := prompty.NewSaveContext() + savedData := instance.Save(saveCtx) + + reloaded, err := prompty.LoadFailureChunk(savedData, loadCtx) + if err != nil { + t.Fatalf("Failed to reload FailureChunk: %v", err) + } + _ = reloaded // No scalar properties to validate + if reloaded.Failure.Outcome != "indeterminate" { + t.Errorf(`Expected Failure.Outcome to be "indeterminate", got %v`, reloaded.Failure.Outcome) + } + if reloaded.Failure.Message != "SSE stream error: connection reset" { + t.Errorf(`Expected Failure.Message to be "SSE stream error: connection reset", got %v`, reloaded.Failure.Message) + } +} + +// TestFailureChunkToJSON tests that ToJSON produces valid JSON +func TestFailureChunkToJSON(t *testing.T) { + jsonData := ` +{ + "failure": { + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" + } +} +` + var data map[string]interface{} + if err := json.Unmarshal([]byte(jsonData), &data); err != nil { + t.Fatalf("Failed to parse JSON: %v", err) + } + + ctx := prompty.NewLoadContext() + instance, err := prompty.LoadFailureChunk(data, ctx) + if err != nil { + t.Fatalf("Failed to load FailureChunk: %v", err) + } + jsonOutput, err := instance.ToJSON() + if err != nil { + t.Fatalf("Failed to convert to JSON: %v", err) + } + + var parsed map[string]interface{} + if err := json.Unmarshal([]byte(jsonOutput), &parsed); err != nil { + t.Fatalf("Failed to parse generated JSON: %v", err) + } + + reloaded, err := prompty.LoadFailureChunk(parsed, ctx) + if err != nil { + t.Fatalf("Failed to reload generated JSON: %v", err) + } + _ = reloaded // No scalar properties to validate + if reloaded.Failure.Outcome != "indeterminate" { + t.Errorf(`Expected Failure.Outcome to be "indeterminate", got %v`, reloaded.Failure.Outcome) + } + if reloaded.Failure.Message != "SSE stream error: connection reset" { + t.Errorf(`Expected Failure.Message to be "SSE stream error: connection reset", got %v`, reloaded.Failure.Message) + } +} + +// TestFailureChunkToYAML tests that ToYAML produces valid YAML +func TestFailureChunkToYAML(t *testing.T) { + jsonData := ` +{ + "failure": { + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" + } +} +` + var data map[string]interface{} + if err := json.Unmarshal([]byte(jsonData), &data); err != nil { + t.Fatalf("Failed to parse JSON: %v", err) + } + + ctx := prompty.NewLoadContext() + instance, err := prompty.LoadFailureChunk(data, ctx) + if err != nil { + t.Fatalf("Failed to load FailureChunk: %v", err) + } + yamlOutput, err := instance.ToYAML() + if err != nil { + t.Fatalf("Failed to convert to YAML: %v", err) + } + + var parsed map[string]interface{} + if err := yaml.Unmarshal([]byte(yamlOutput), &parsed); err != nil { + t.Fatalf("Failed to parse generated YAML: %v", err) + } + + reloaded, err := prompty.LoadFailureChunk(parsed, ctx) + if err != nil { + t.Fatalf("Failed to reload generated YAML: %v", err) + } + _ = reloaded // No scalar properties to validate + if reloaded.Failure.Outcome != "indeterminate" { + t.Errorf(`Expected Failure.Outcome to be "indeterminate", got %v`, reloaded.Failure.Outcome) + } + if reloaded.Failure.Message != "SSE stream error: connection reset" { + t.Errorf(`Expected Failure.Message to be "SSE stream error: connection reset", got %v`, reloaded.Failure.Message) + } +} + +// TestFailureChunkFromJSONInvalid rejects malformed JSON instead of silently defaulting +func TestFailureChunkFromJSONInvalid(t *testing.T) { + if _, err := prompty.FailureChunkFromJSON("{"); err == nil { + t.Fatalf("Expected malformed JSON to fail") + } +} diff --git a/runtime/python/prompty/tests/model/events/test_failure_chunk.py b/runtime/python/prompty/tests/model/events/test_failure_chunk.py new file mode 100644 index 000000000..a13d0f481 --- /dev/null +++ b/runtime/python/prompty/tests/model/events/test_failure_chunk.py @@ -0,0 +1,85 @@ +# +import json + +import yaml + +from prompty.model import FailureChunk + + +def test_load_json_failurechunk(): + json_data = r""" + { + "failure": { + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" + } + } + """ + data = json.loads(json_data, strict=False) + instance = FailureChunk.load(data) + assert instance is not None + + +def test_load_yaml_failurechunk(): + yaml_data = r""" + failure: + outcome: indeterminate + message: "SSE stream error: connection reset" + + """ + data = yaml.load(yaml_data, Loader=yaml.FullLoader) + instance = FailureChunk.load(data) + assert instance is not None + + +def test_roundtrip_json_failurechunk(): + """Test that load -> save -> load produces equivalent data.""" + json_data = r""" + { + "failure": { + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" + } + } + """ + original_data = json.loads(json_data, strict=False) + instance = FailureChunk.load(original_data) + saved_data = instance.save() + reloaded = FailureChunk.load(saved_data) + assert reloaded is not None + + +def test_to_json_failurechunk(): + """Test that to_json produces valid JSON.""" + json_data = r""" + { + "failure": { + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" + } + } + """ + data = json.loads(json_data, strict=False) + instance = FailureChunk.load(data) + json_output = instance.to_json() + assert json_output is not None + parsed = json.loads(json_output) + assert isinstance(parsed, dict) + + +def test_to_yaml_failurechunk(): + """Test that to_yaml produces valid YAML.""" + json_data = r""" + { + "failure": { + "outcome": "indeterminate", + "message": "SSE stream error: connection reset" + } + } + """ + data = json.loads(json_data, strict=False) + instance = FailureChunk.load(data) + yaml_output = instance.to_yaml() + assert yaml_output is not None + parsed = yaml.safe_load(yaml_output) + assert isinstance(parsed, dict) diff --git a/runtime/typescript/packages/core/tests/model/events/failure-chunk.test.ts b/runtime/typescript/packages/core/tests/model/events/failure-chunk.test.ts index d55be9fcb..ed348ddf7 100644 --- a/runtime/typescript/packages/core/tests/model/events/failure-chunk.test.ts +++ b/runtime/typescript/packages/core/tests/model/events/failure-chunk.test.ts @@ -17,6 +17,36 @@ describe("FailureChunk", () => { }); }); + describe("JSON serialization", () => { + it("should load from JSON - example 1", () => { + const json = `{\n "failure": {\n "outcome": "indeterminate",\n "message": "SSE stream error: connection reset"\n }\n}`; + const instance = FailureChunk.fromJson(json); + expect(instance).toBeDefined(); + }); + + it("should round-trip JSON - example 1", () => { + const json = `{\n "failure": {\n "outcome": "indeterminate",\n "message": "SSE stream error: connection reset"\n }\n}`; + const instance = FailureChunk.fromJson(json); + const output = instance.toJson(); + const reloaded = FailureChunk.fromJson(output); + }); + }); + + describe("YAML serialization", () => { + it("should load from YAML - example 1", () => { + const yaml = `failure:\n outcome: indeterminate\n message: "SSE stream error: connection reset"\n`; + const instance = FailureChunk.fromYaml(yaml); + expect(instance).toBeDefined(); + }); + + it("should round-trip YAML - example 1", () => { + const yaml = `failure:\n outcome: indeterminate\n message: "SSE stream error: connection reset"\n`; + const instance = FailureChunk.fromYaml(yaml); + const output = instance.toYaml(); + const reloaded = FailureChunk.fromYaml(output); + }); + }); + describe("load and save", () => { it("should load from dictionary", () => { const data: Record = {}; diff --git a/schema/model/events/stream-chunks.tsp b/schema/model/events/stream-chunks.tsp index 0b6ff2a90..650832e49 100644 --- a/schema/model/events/stream-chunks.tsp +++ b/schema/model/events/stream-chunks.tsp @@ -117,5 +117,11 @@ model FailureChunk extends StreamChunk { kind: "failure"; @doc("The classified stream failure") + @sample(#{ + failure: #{ + outcome: "indeterminate", + message: "SSE stream error: connection reset", + }, + }) failure: StreamFailure; } diff --git a/schema/tsp-output/.typra-generated/manifest.json b/schema/tsp-output/.typra-generated/manifest.json index d11643e00..84fd96b1f 100644 --- a/schema/tsp-output/.typra-generated/manifest.json +++ b/schema/tsp-output/.typra-generated/manifest.json @@ -4003,6 +4003,11 @@ "path": "../runtime/python/prompty/tests/model/events/test_error_event_payload.py", "marker": true }, + { + "outputRoot": "../runtime/python/prompty/tests/model", + "path": "../runtime/python/prompty/tests/model/events/test_failure_chunk.py", + "marker": true + }, { "outputRoot": "../runtime/python/prompty/tests/model", "path": "../runtime/python/prompty/tests/model/events/test_harness_context.py", diff --git a/web/src/content/docs/reference/FailureChunk.md b/web/src/content/docs/reference/FailureChunk.md index 0f1c05004..522b641ec 100644 --- a/web/src/content/docs/reference/FailureChunk.md +++ b/web/src/content/docs/reference/FailureChunk.md @@ -35,6 +35,14 @@ classDiagram FailureChunk *-- StreamFailure ``` +## Yaml Example + +```yaml +failure: + outcome: indeterminate + message: "SSE stream error: connection reset" +``` + ## Properties | Name | Type | Description | From e75136343bcacdce81b4ac264979814834cb527c Mon Sep 17 00:00:00 2001 From: Seth Juarez Date: Tue, 4 Aug 2026 03:17:30 -0700 Subject: [PATCH 09/10] test(schema): cover failure discriminator round trips Sample the canonical failure discriminator so generated conversion tests assert it survives JSON and YAML round trips in every configured runtime. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../events/FailureChunkConversionTests.cs | 10 ++++++ .../go/prompty/model/failure_chunk_test.go | 35 +++++++++++++++---- .../tests/model/events/test_failure_chunk.py | 8 +++++ .../tests/model/events/failure-chunk.test.ts | 12 ++++--- schema/model/events/stream-chunks.tsp | 1 + .../content/docs/reference/FailureChunk.md | 1 + 6 files changed, 56 insertions(+), 11 deletions(-) diff --git a/runtime/csharp/Prompty.Core.Tests/Model/events/FailureChunkConversionTests.cs b/runtime/csharp/Prompty.Core.Tests/Model/events/FailureChunkConversionTests.cs index 66f9fb113..601898294 100644 --- a/runtime/csharp/Prompty.Core.Tests/Model/events/FailureChunkConversionTests.cs +++ b/runtime/csharp/Prompty.Core.Tests/Model/events/FailureChunkConversionTests.cs @@ -12,6 +12,7 @@ public class FailureChunkConversionTests public void LoadYamlInput() { string yamlData = """ +kind: failure failure: outcome: indeterminate message: "SSE stream error: connection reset" @@ -21,6 +22,7 @@ public void LoadYamlInput() var instance = FailureChunk.FromYaml(yamlData); Assert.NotNull(instance); + Assert.Equal("failure", instance.Kind); } [Fact] @@ -28,6 +30,7 @@ public void LoadJsonInput() { string jsonData = """ { + "kind": "failure", "failure": { "outcome": "indeterminate", "message": "SSE stream error: connection reset" @@ -37,6 +40,7 @@ public void LoadJsonInput() var instance = FailureChunk.FromJson(jsonData); Assert.NotNull(instance); + Assert.Equal("failure", instance.Kind); } [Fact] @@ -45,6 +49,7 @@ public void RoundtripJson() // Test that FromJson -> ToJson -> FromJson produces equivalent data string jsonData = """ { + "kind": "failure", "failure": { "outcome": "indeterminate", "message": "SSE stream error: connection reset" @@ -60,6 +65,7 @@ public void RoundtripJson() var reloaded = FailureChunk.FromJson(json); Assert.NotNull(reloaded); + Assert.Equal("failure", reloaded.Kind); } [Fact] @@ -67,6 +73,7 @@ public void RoundtripYaml() { // Test that FromYaml -> ToYaml -> FromYaml produces equivalent data string yamlData = """ +kind: failure failure: outcome: indeterminate message: "SSE stream error: connection reset" @@ -81,6 +88,7 @@ public void RoundtripYaml() var reloaded = FailureChunk.FromYaml(yaml); Assert.NotNull(reloaded); + Assert.Equal("failure", reloaded.Kind); } [Fact] @@ -88,6 +96,7 @@ public void ToJsonProducesValidJson() { string jsonData = """ { + "kind": "failure", "failure": { "outcome": "indeterminate", "message": "SSE stream error: connection reset" @@ -107,6 +116,7 @@ public void ToJsonProducesValidJson() public void ToYamlProducesValidYaml() { string yamlData = """ +kind: failure failure: outcome: indeterminate message: "SSE stream error: connection reset" diff --git a/runtime/go/prompty/model/failure_chunk_test.go b/runtime/go/prompty/model/failure_chunk_test.go index 0a7338f1b..9decfaab9 100644 --- a/runtime/go/prompty/model/failure_chunk_test.go +++ b/runtime/go/prompty/model/failure_chunk_test.go @@ -16,6 +16,7 @@ import ( func TestFailureChunkLoadJSON(t *testing.T) { jsonData := ` { + "kind": "failure", "failure": { "outcome": "indeterminate", "message": "SSE stream error: connection reset" @@ -32,7 +33,9 @@ func TestFailureChunkLoadJSON(t *testing.T) { if err != nil { t.Fatalf("Failed to load FailureChunk: %v", err) } - _ = instance // No scalar properties to validate + if instance.Kind != "failure" { + t.Errorf(`Expected Kind to be "failure", got %v`, instance.Kind) + } if instance.Failure.Outcome != "indeterminate" { t.Errorf(`Expected Failure.Outcome to be "indeterminate", got %v`, instance.Failure.Outcome) } @@ -44,6 +47,7 @@ func TestFailureChunkLoadJSON(t *testing.T) { // TestFailureChunkLoadYAML tests loading FailureChunk from YAML func TestFailureChunkLoadYAML(t *testing.T) { yamlData := ` +kind: failure failure: outcome: indeterminate message: "SSE stream error: connection reset" @@ -59,7 +63,9 @@ failure: if err != nil { t.Fatalf("Failed to load FailureChunk: %v", err) } - _ = instance // No scalar properties to validate + if instance.Kind != "failure" { + t.Errorf(`Expected Kind to be "failure", got %v`, instance.Kind) + } if instance.Failure.Outcome != "indeterminate" { t.Errorf(`Expected Failure.Outcome to be "indeterminate", got %v`, instance.Failure.Outcome) } @@ -72,6 +78,7 @@ failure: func TestFailureChunkFromJSON(t *testing.T) { jsonData := ` { + "kind": "failure", "failure": { "outcome": "indeterminate", "message": "SSE stream error: connection reset" @@ -83,7 +90,9 @@ func TestFailureChunkFromJSON(t *testing.T) { if err != nil { t.Fatalf("Failed to load FailureChunk from JSON helper: %v", err) } - _ = instance // No scalar properties to validate + if instance.Kind != "failure" { + t.Errorf(`Expected Kind to be "failure", got %v`, instance.Kind) + } if instance.Failure.Outcome != "indeterminate" { t.Errorf(`Expected Failure.Outcome to be "indeterminate", got %v`, instance.Failure.Outcome) } @@ -95,6 +104,7 @@ func TestFailureChunkFromJSON(t *testing.T) { // TestFailureChunkFromYAML tests loading FailureChunk through the generated YAML helper func TestFailureChunkFromYAML(t *testing.T) { yamlData := ` +kind: failure failure: outcome: indeterminate message: "SSE stream error: connection reset" @@ -105,7 +115,9 @@ failure: if err != nil { t.Fatalf("Failed to load FailureChunk from YAML helper: %v", err) } - _ = instance // No scalar properties to validate + if instance.Kind != "failure" { + t.Errorf(`Expected Kind to be "failure", got %v`, instance.Kind) + } if instance.Failure.Outcome != "indeterminate" { t.Errorf(`Expected Failure.Outcome to be "indeterminate", got %v`, instance.Failure.Outcome) } @@ -118,6 +130,7 @@ failure: func TestFailureChunkRoundtrip(t *testing.T) { jsonData := ` { + "kind": "failure", "failure": { "outcome": "indeterminate", "message": "SSE stream error: connection reset" @@ -141,7 +154,9 @@ func TestFailureChunkRoundtrip(t *testing.T) { if err != nil { t.Fatalf("Failed to reload FailureChunk: %v", err) } - _ = reloaded // No scalar properties to validate + if reloaded.Kind != "failure" { + t.Errorf(`Expected Kind to be "failure", got %v`, reloaded.Kind) + } if reloaded.Failure.Outcome != "indeterminate" { t.Errorf(`Expected Failure.Outcome to be "indeterminate", got %v`, reloaded.Failure.Outcome) } @@ -154,6 +169,7 @@ func TestFailureChunkRoundtrip(t *testing.T) { func TestFailureChunkToJSON(t *testing.T) { jsonData := ` { + "kind": "failure", "failure": { "outcome": "indeterminate", "message": "SSE stream error: connection reset" @@ -184,7 +200,9 @@ func TestFailureChunkToJSON(t *testing.T) { if err != nil { t.Fatalf("Failed to reload generated JSON: %v", err) } - _ = reloaded // No scalar properties to validate + if reloaded.Kind != "failure" { + t.Errorf(`Expected Kind to be "failure", got %v`, reloaded.Kind) + } if reloaded.Failure.Outcome != "indeterminate" { t.Errorf(`Expected Failure.Outcome to be "indeterminate", got %v`, reloaded.Failure.Outcome) } @@ -197,6 +215,7 @@ func TestFailureChunkToJSON(t *testing.T) { func TestFailureChunkToYAML(t *testing.T) { jsonData := ` { + "kind": "failure", "failure": { "outcome": "indeterminate", "message": "SSE stream error: connection reset" @@ -227,7 +246,9 @@ func TestFailureChunkToYAML(t *testing.T) { if err != nil { t.Fatalf("Failed to reload generated YAML: %v", err) } - _ = reloaded // No scalar properties to validate + if reloaded.Kind != "failure" { + t.Errorf(`Expected Kind to be "failure", got %v`, reloaded.Kind) + } if reloaded.Failure.Outcome != "indeterminate" { t.Errorf(`Expected Failure.Outcome to be "indeterminate", got %v`, reloaded.Failure.Outcome) } diff --git a/runtime/python/prompty/tests/model/events/test_failure_chunk.py b/runtime/python/prompty/tests/model/events/test_failure_chunk.py index a13d0f481..9dd4b96bd 100644 --- a/runtime/python/prompty/tests/model/events/test_failure_chunk.py +++ b/runtime/python/prompty/tests/model/events/test_failure_chunk.py @@ -9,6 +9,7 @@ def test_load_json_failurechunk(): json_data = r""" { + "kind": "failure", "failure": { "outcome": "indeterminate", "message": "SSE stream error: connection reset" @@ -18,10 +19,12 @@ def test_load_json_failurechunk(): data = json.loads(json_data, strict=False) instance = FailureChunk.load(data) assert instance is not None + assert instance.kind == "failure" def test_load_yaml_failurechunk(): yaml_data = r""" + kind: failure failure: outcome: indeterminate message: "SSE stream error: connection reset" @@ -30,12 +33,14 @@ def test_load_yaml_failurechunk(): data = yaml.load(yaml_data, Loader=yaml.FullLoader) instance = FailureChunk.load(data) assert instance is not None + assert instance.kind == "failure" def test_roundtrip_json_failurechunk(): """Test that load -> save -> load produces equivalent data.""" json_data = r""" { + "kind": "failure", "failure": { "outcome": "indeterminate", "message": "SSE stream error: connection reset" @@ -47,12 +52,14 @@ def test_roundtrip_json_failurechunk(): saved_data = instance.save() reloaded = FailureChunk.load(saved_data) assert reloaded is not None + assert reloaded.kind == "failure" def test_to_json_failurechunk(): """Test that to_json produces valid JSON.""" json_data = r""" { + "kind": "failure", "failure": { "outcome": "indeterminate", "message": "SSE stream error: connection reset" @@ -71,6 +78,7 @@ def test_to_yaml_failurechunk(): """Test that to_yaml produces valid YAML.""" json_data = r""" { + "kind": "failure", "failure": { "outcome": "indeterminate", "message": "SSE stream error: connection reset" diff --git a/runtime/typescript/packages/core/tests/model/events/failure-chunk.test.ts b/runtime/typescript/packages/core/tests/model/events/failure-chunk.test.ts index ed348ddf7..68fc107b1 100644 --- a/runtime/typescript/packages/core/tests/model/events/failure-chunk.test.ts +++ b/runtime/typescript/packages/core/tests/model/events/failure-chunk.test.ts @@ -19,31 +19,35 @@ describe("FailureChunk", () => { describe("JSON serialization", () => { it("should load from JSON - example 1", () => { - const json = `{\n "failure": {\n "outcome": "indeterminate",\n "message": "SSE stream error: connection reset"\n }\n}`; + const json = `{\n "kind": "failure",\n "failure": {\n "outcome": "indeterminate",\n "message": "SSE stream error: connection reset"\n }\n}`; const instance = FailureChunk.fromJson(json); expect(instance).toBeDefined(); + expect(instance.kind).toEqual("failure"); }); it("should round-trip JSON - example 1", () => { - const json = `{\n "failure": {\n "outcome": "indeterminate",\n "message": "SSE stream error: connection reset"\n }\n}`; + const json = `{\n "kind": "failure",\n "failure": {\n "outcome": "indeterminate",\n "message": "SSE stream error: connection reset"\n }\n}`; const instance = FailureChunk.fromJson(json); const output = instance.toJson(); const reloaded = FailureChunk.fromJson(output); + expect(reloaded.kind).toEqual(instance.kind); }); }); describe("YAML serialization", () => { it("should load from YAML - example 1", () => { - const yaml = `failure:\n outcome: indeterminate\n message: "SSE stream error: connection reset"\n`; + const yaml = `kind: failure\nfailure:\n outcome: indeterminate\n message: "SSE stream error: connection reset"\n`; const instance = FailureChunk.fromYaml(yaml); expect(instance).toBeDefined(); + expect(instance.kind).toEqual("failure"); }); it("should round-trip YAML - example 1", () => { - const yaml = `failure:\n outcome: indeterminate\n message: "SSE stream error: connection reset"\n`; + const yaml = `kind: failure\nfailure:\n outcome: indeterminate\n message: "SSE stream error: connection reset"\n`; const instance = FailureChunk.fromYaml(yaml); const output = instance.toYaml(); const reloaded = FailureChunk.fromYaml(output); + expect(reloaded.kind).toEqual(instance.kind); }); }); diff --git a/schema/model/events/stream-chunks.tsp b/schema/model/events/stream-chunks.tsp index 650832e49..eb812725b 100644 --- a/schema/model/events/stream-chunks.tsp +++ b/schema/model/events/stream-chunks.tsp @@ -114,6 +114,7 @@ model ErrorChunk extends StreamChunk { */ model FailureChunk extends StreamChunk { @doc("The kind identifier for classified failure chunks") + @sample(#{ kind: "failure" }) kind: "failure"; @doc("The classified stream failure") diff --git a/web/src/content/docs/reference/FailureChunk.md b/web/src/content/docs/reference/FailureChunk.md index 522b641ec..172e620e7 100644 --- a/web/src/content/docs/reference/FailureChunk.md +++ b/web/src/content/docs/reference/FailureChunk.md @@ -38,6 +38,7 @@ classDiagram ## Yaml Example ```yaml +kind: failure failure: outcome: indeterminate message: "SSE stream error: connection reset" From ae908bd2b6b1861d2285789b4b880e0ea54e067b Mon Sep 17 00:00:00 2001 From: Seth Juarez Date: Tue, 4 Aug 2026 03:17:36 -0700 Subject: [PATCH 10/10] fix(typescript): close cancelled provider streams Run upstream iterator cleanup from async-generator finally blocks so consumer cancellation releases SSE resources without double-closing failure paths. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../packages/anthropic/src/processor.ts | 132 +++++++++------- .../anthropic/tests/stream-failures.test.ts | 34 ++++ .../packages/openai/src/processor.ts | 147 +++++++++++------- .../tests/stream-failure-vectors.test.ts | 45 +++++- 4 files changed, 246 insertions(+), 112 deletions(-) diff --git a/runtime/typescript/packages/anthropic/src/processor.ts b/runtime/typescript/packages/anthropic/src/processor.ts index 851140d0e..ca525b85b 100644 --- a/runtime/typescript/packages/anthropic/src/processor.ts +++ b/runtime/typescript/packages/anthropic/src/processor.ts @@ -20,7 +20,10 @@ import { createStructuredResult } from "@prompty/core"; export class AnthropicProcessor implements Processor { async process(agent: Prompty, response: unknown): Promise { return traceSpan("AnthropicProcessor", async (emit) => { - emit("signature", "prompty.anthropic.processor.AnthropicProcessor.invoke"); + emit( + "signature", + "prompty.anthropic.processor.AnthropicProcessor.invoke", + ); emit("inputs", { data: response }); const result = processResponse(agent, response); // Don't emit result for streaming — it's a generator, not a value @@ -60,9 +63,7 @@ export function processResponse(agent: Prompty, response: unknown): unknown { /** Type guard for async iterables (PromptyStream or raw SDK stream). */ function isAsyncIterable(value: unknown): value is AsyncIterable { return ( - typeof value === "object" && - value !== null && - Symbol.asyncIterator in value + typeof value === "object" && value !== null && Symbol.asyncIterator in value ); } @@ -85,59 +86,76 @@ async function* streamGenerator( { id: string; name: string; arguments: string } > = new Map(); const iterator = response[Symbol.asyncIterator](); + let iteratorClosed = false; + let iteratorExhausted = false; - while (true) { - let next: IteratorResult; - try { - next = await iterator.next(); - } catch (error) { - await closeIterator(iterator); - yield new FailureChunk({ - failure: new StreamFailure({ - outcome: "indeterminate", - message: error instanceof Error ? error.message : String(error), - }), - }); - return; - } - if (next.done) break; - - const event = next.value; - const e = event as Record; - const eventType = e.type as string | undefined; - - if (eventType === "content_block_delta") { - const delta = e.delta as Record | undefined; - if (!delta) continue; - - if (delta.type === "text_delta") { - yield delta.text as string; - } else if (delta.type === "input_json_delta") { - // Accumulate partial JSON for tool arguments - const idx = e.index as number; - const acc = toolCallAcc.get(idx); - if (acc) { - acc.arguments += (delta.partial_json ?? "") as string; - } - } - } else if (eventType === "content_block_start") { - const block = e.content_block as Record | undefined; - if (block?.type === "tool_use") { - const idx = e.index as number; - toolCallAcc.set(idx, { - id: (block.id ?? "") as string, - name: (block.name ?? "") as string, - arguments: "", + const close = async (): Promise => { + if (iteratorClosed) return; + iteratorClosed = true; + await closeIterator(iterator); + }; + + try { + while (true) { + let next: IteratorResult; + try { + next = await iterator.next(); + } catch (error) { + await close(); + yield new FailureChunk({ + failure: new StreamFailure({ + outcome: "indeterminate", + message: error instanceof Error ? error.message : String(error), + }), }); + return; + } + if (next.done) { + iteratorExhausted = true; + break; + } + + const event = next.value; + const e = event as Record; + const eventType = e.type as string | undefined; + + if (eventType === "content_block_delta") { + const delta = e.delta as Record | undefined; + if (!delta) continue; + + if (delta.type === "text_delta") { + yield delta.text as string; + } else if (delta.type === "input_json_delta") { + // Accumulate partial JSON for tool arguments + const idx = e.index as number; + const acc = toolCallAcc.get(idx); + if (acc) { + acc.arguments += (delta.partial_json ?? "") as string; + } + } + } else if (eventType === "content_block_start") { + const block = e.content_block as Record | undefined; + if (block?.type === "tool_use") { + const idx = e.index as number; + toolCallAcc.set(idx, { + id: (block.id ?? "") as string, + name: (block.name ?? "") as string, + arguments: "", + }); + } } } - } - // Yield accumulated tool calls at the end of the stream - const sortedIndices = [...toolCallAcc.keys()].sort((a, b) => a - b); - for (const idx of sortedIndices) { - const tc = toolCallAcc.get(idx)!; - yield { id: tc.id, name: tc.name, arguments: tc.arguments } as ToolCall; + // Yield accumulated tool calls at the end of the stream + const sortedIndices = [...toolCallAcc.keys()].sort((a, b) => a - b); + for (const idx of sortedIndices) { + const tc = toolCallAcc.get(idx)!; + yield { id: tc.id, name: tc.name, arguments: tc.arguments } as ToolCall; + } + } finally { + if (!iteratorExhausted) { + await close(); + } } } @@ -147,7 +165,10 @@ async function closeIterator(iterator: AsyncIterator): Promise { await iterator.return(); } catch (error) { if (typeof globalThis.console?.debug === "function") { - globalThis.console.debug("Failed to close Anthropic response stream:", error); + globalThis.console.debug( + "Failed to close Anthropic response stream:", + error, + ); } } } @@ -209,7 +230,10 @@ function processMessages( // Structured output — JSON parse when outputs schema exists if (agent.outputs && agent.outputs.length > 0) { try { - return createStructuredResult(JSON.parse(text) as Record, text); + return createStructuredResult( + JSON.parse(text) as Record, + text, + ); } catch { return text; } diff --git a/runtime/typescript/packages/anthropic/tests/stream-failures.test.ts b/runtime/typescript/packages/anthropic/tests/stream-failures.test.ts index d8147bb5f..a20df622a 100644 --- a/runtime/typescript/packages/anthropic/tests/stream-failures.test.ts +++ b/runtime/typescript/packages/anthropic/tests/stream-failures.test.ts @@ -4,6 +4,40 @@ import { describe, expect, it } from "vitest"; import { processResponse } from "../src/processor.js"; describe("Anthropic classified stream failures", () => { + it("closes the provider stream when the consumer stops early", async () => { + let closeCount = 0; + const response: AsyncIterable = { + [Symbol.asyncIterator](): AsyncIterator { + return { + async next(): Promise> { + return { + done: false, + value: { + type: "content_block_delta", + delta: { type: "text_delta", text: "partial" }, + }, + }; + }, + async return(): Promise> { + closeCount += 1; + return { done: true, value: undefined }; + }, + }; + }, + }; + const agent = new Prompty({ name: "stream-cancel", model: "claude-test" }); + + for await (const item of processResponse( + agent, + response, + ) as AsyncIterable) { + expect(item).toBe("partial"); + break; + } + + expect(closeCount).toBe(1); + }); + it("closes the provider stream after a transport failure", async () => { let closed = false; const response: AsyncIterable = { diff --git a/runtime/typescript/packages/openai/src/processor.ts b/runtime/typescript/packages/openai/src/processor.ts index 21165e4ca..9d47c85da 100644 --- a/runtime/typescript/packages/openai/src/processor.ts +++ b/runtime/typescript/packages/openai/src/processor.ts @@ -74,9 +74,7 @@ export function processResponse(agent: Prompty, response: unknown): unknown { /** Type guard for async iterables (PromptyStream or raw SDK stream). */ function isAsyncIterable(value: unknown): value is AsyncIterable { return ( - typeof value === "object" && - value !== null && - Symbol.asyncIterator in value + typeof value === "object" && value !== null && Symbol.asyncIterator in value ); } @@ -94,68 +92,95 @@ function isAsyncIterable(value: unknown): value is AsyncIterable { async function* streamGenerator( response: AsyncIterable, ): AsyncGenerator { - const toolCallAcc: Map = new Map(); + const toolCallAcc: Map< + number, + { id: string; name: string; arguments: string } + > = new Map(); const iterator = response[Symbol.asyncIterator](); + let iteratorClosed = false; + let iteratorExhausted = false; - while (true) { - let next: IteratorResult; - try { - next = await iterator.next(); - } catch (error) { - await closeIterator(iterator); - yield failureChunk("indeterminate", errorMessage(error)); - return; - } - if (next.done) break; + const close = async (): Promise => { + if (iteratorClosed) return; + iteratorClosed = true; + await closeIterator(iterator); + }; - const chunk = next.value; - const c = chunk as Record; - const choices = c.choices as Record[] | undefined; - if (!choices || choices.length === 0) continue; + try { + while (true) { + let next: IteratorResult; + try { + next = await iterator.next(); + } catch (error) { + await close(); + yield failureChunk("indeterminate", errorMessage(error)); + return; + } + if (next.done) { + iteratorExhausted = true; + break; + } - const delta = (choices[0] as Record).delta as Record | undefined; - if (!delta) continue; + const chunk = next.value; + const c = chunk as Record; + const choices = c.choices as Record[] | undefined; + if (!choices || choices.length === 0) continue; - // Content - if (delta.content != null) { - yield delta.content as string; - } + const delta = (choices[0] as Record).delta as + | Record + | undefined; + if (!delta) continue; - // Tool call deltas — accumulate index-keyed partial chunks - const tcDeltas = delta.tool_calls as Record[] | undefined; - if (tcDeltas) { - for (const tcDelta of tcDeltas) { - const idx = tcDelta.index as number; - if (!toolCallAcc.has(idx)) { - toolCallAcc.set(idx, { id: "", name: "", arguments: "" }); - } - const acc = toolCallAcc.get(idx)!; - if (tcDelta.id) acc.id = tcDelta.id as string; - const fn = tcDelta.function as Record | undefined; - if (fn) { - if (fn.name) acc.name = fn.name as string; - if (fn.arguments) acc.arguments += fn.arguments as string; + // Content + if (delta.content != null) { + yield delta.content as string; + } + + // Tool call deltas — accumulate index-keyed partial chunks + const tcDeltas = delta.tool_calls as + | Record[] + | undefined; + if (tcDeltas) { + for (const tcDelta of tcDeltas) { + const idx = tcDelta.index as number; + if (!toolCallAcc.has(idx)) { + toolCallAcc.set(idx, { id: "", name: "", arguments: "" }); + } + const acc = toolCallAcc.get(idx)!; + if (tcDelta.id) acc.id = tcDelta.id as string; + const fn = tcDelta.function as Record | undefined; + if (fn) { + if (fn.name) acc.name = fn.name as string; + if (fn.arguments) acc.arguments += fn.arguments as string; + } } } - } - // Refusal - if (delta.refusal != null) { - await closeIterator(iterator); - yield failureChunk("determinate", `Model refused: ${delta.refusal}`); - return; + // Refusal + if (delta.refusal != null) { + await close(); + yield failureChunk("determinate", `Model refused: ${delta.refusal}`); + return; + } } - } - // Yield accumulated tool calls at the end of the stream - const sortedIndices = [...toolCallAcc.keys()].sort((a, b) => a - b); - for (const idx of sortedIndices) { - const tc = toolCallAcc.get(idx)!; - yield { id: tc.id, name: tc.name, arguments: tc.arguments } as ToolCall; + // Yield accumulated tool calls at the end of the stream + const sortedIndices = [...toolCallAcc.keys()].sort((a, b) => a - b); + for (const idx of sortedIndices) { + const tc = toolCallAcc.get(idx)!; + yield { id: tc.id, name: tc.name, arguments: tc.arguments } as ToolCall; + } + } finally { + if (!iteratorExhausted) { + await close(); + } } } -function failureChunk(outcome: "determinate" | "indeterminate", message: string): FailureChunk { +function failureChunk( + outcome: "determinate" | "indeterminate", + message: string, +): FailureChunk { return new FailureChunk({ failure: new StreamFailure({ outcome, message }), }); @@ -171,7 +196,10 @@ async function closeIterator(iterator: AsyncIterator): Promise { await iterator.return(); } catch (error) { if (typeof globalThis.console?.debug === "function") { - globalThis.console.debug("Failed to close OpenAI response stream:", error); + globalThis.console.debug( + "Failed to close OpenAI response stream:", + error, + ); } } } @@ -216,7 +244,10 @@ function processResponsesApi( // Structured output — JSON parse when outputs schema exists if (agent.outputs && agent.outputs.length > 0) { try { - return createStructuredResult(JSON.parse(outputText) as Record, outputText); + return createStructuredResult( + JSON.parse(outputText) as Record, + outputText, + ); } catch { return outputText; } @@ -243,7 +274,10 @@ function processResponsesApi( const text = texts.join(""); if (agent.outputs && agent.outputs.length > 0) { try { - return createStructuredResult(JSON.parse(text) as Record, text); + return createStructuredResult( + JSON.parse(text) as Record, + text, + ); } catch { return text; } @@ -295,7 +329,10 @@ function processChatCompletion( // Structured output — JSON parse when outputs schema exists if (agent.outputs && agent.outputs.length > 0) { try { - return createStructuredResult(JSON.parse(content) as Record, content); + return createStructuredResult( + JSON.parse(content) as Record, + content, + ); } catch { return content; } diff --git a/runtime/typescript/packages/openai/tests/stream-failure-vectors.test.ts b/runtime/typescript/packages/openai/tests/stream-failure-vectors.test.ts index af693e955..3876b0267 100644 --- a/runtime/typescript/packages/openai/tests/stream-failure-vectors.test.ts +++ b/runtime/typescript/packages/openai/tests/stream-failure-vectors.test.ts @@ -10,17 +10,25 @@ interface StreamFailureVector { name: string; input: { provider: string; - events: Array<{ kind: "provider"; value: Record } | { kind: "transportError"; message: string }>; + events: Array< + | { kind: "provider"; value: Record } + | { kind: "transportError"; message: string } + >; }; expected: { chunks: unknown[] }; } function loadVectors(): StreamFailureVector[] { - const path = resolve(import.meta.dirname, "../../../../../spec/vectors/process/stream_failure_vectors.json"); + const path = resolve( + import.meta.dirname, + "../../../../../spec/vectors/process/stream_failure_vectors.json", + ); return JSON.parse(readFileSync(path, "utf8")) as StreamFailureVector[]; } -function responseFromVector(vector: StreamFailureVector): AsyncIterable { +function responseFromVector( + vector: StreamFailureVector, +): AsyncIterable { return { async *[Symbol.asyncIterator](): AsyncIterator { for (const event of vector.input.events) { @@ -60,6 +68,37 @@ function closableResponseFromVector( } describe("OpenAI classified stream failure vectors", () => { + it("closes the provider stream when the consumer stops early", async () => { + let closeCount = 0; + const response: AsyncIterable = { + [Symbol.asyncIterator](): AsyncIterator { + return { + async next(): Promise> { + return { + done: false, + value: { choices: [{ delta: { content: "partial" } }] }, + }; + }, + async return(): Promise> { + closeCount += 1; + return { done: true, value: undefined }; + }, + }; + }, + }; + const agent = new Prompty({ name: "stream-cancel", model: "gpt-test" }); + + for await (const item of processResponse( + agent, + response, + ) as AsyncIterable) { + expect(item).toBe("partial"); + break; + } + + expect(closeCount).toBe(1); + }); + for (const vector of loadVectors()) { it(vector.name, async () => { expect(vector.input.provider).toBe("openai");