Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,21 @@ namespace Speechify
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::Speechify.Error))]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(int))]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::System.DateTime))]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::Speechify.V1FilesGetParametersKind), TypeInfoPropertyName = "V1FilesGetParametersKind2")]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::Speechify.FileKind), TypeInfoPropertyName = "FileKind2")]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::Speechify.FileSource))]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::Speechify.File))]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::Speechify.ListFilesResponse))]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::System.Collections.Generic.IList<global::Speechify.File>))]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::Speechify.V1FilesGetParametersKind), TypeInfoPropertyName = "V1FilesGetParametersKind2")]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::Speechify.ListFilesResponse))]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::Speechify.V1FilesPostRequestBodyContentMultipartFormDataSchemaKind), TypeInfoPropertyName = "V1FilesPostRequestBodyContentMultipartFormDataSchemaKind2")]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::Speechify.UploadRequest2))]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(bool?))]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(long?))]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::Speechify.ErrorCode?), TypeInfoPropertyName = "NullableErrorCode2")]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(int?))]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::System.DateTime?))]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::Speechify.V1FilesGetParametersKind?), TypeInfoPropertyName = "NullableV1FilesGetParametersKind2")]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::Speechify.FileKind?), TypeInfoPropertyName = "NullableFileKind2")]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::Speechify.V1FilesGetParametersKind?), TypeInfoPropertyName = "NullableV1FilesGetParametersKind2")]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::Speechify.V1FilesPostRequestBodyContentMultipartFormDataSchemaKind?), TypeInfoPropertyName = "NullableV1FilesPostRequestBodyContentMultipartFormDataSchemaKind2")]
[global::System.Text.Json.Serialization.JsonSerializable(typeof(global::System.Collections.Generic.List<global::Speechify.File>))]
internal sealed partial class FilesSourceGenerationContextChunk0 : global::System.Text.Json.Serialization.JsonSerializerContext
Expand Down Expand Up @@ -115,14 +115,14 @@ public override bool CanConvert(global::System.Type typeToConvert)

|| typeToConvert == typeof(global::Speechify.ErrorCode?)

|| typeToConvert == typeof(global::Speechify.V1FilesGetParametersKind)

|| typeToConvert == typeof(global::Speechify.V1FilesGetParametersKind?)

|| typeToConvert == typeof(global::Speechify.FileKind)

|| typeToConvert == typeof(global::Speechify.FileKind?)

|| typeToConvert == typeof(global::Speechify.V1FilesGetParametersKind)

|| typeToConvert == typeof(global::Speechify.V1FilesGetParametersKind?)

|| typeToConvert == typeof(global::Speechify.V1FilesPostRequestBodyContentMultipartFormDataSchemaKind)

|| typeToConvert == typeof(global::Speechify.V1FilesPostRequestBodyContentMultipartFormDataSchemaKind?);
Expand All @@ -142,24 +142,24 @@ public override bool CanConvert(global::System.Type typeToConvert)
return new global::Speechify.JsonConverters.ErrorCodeNullableJsonConverter();
}

if (typeToConvert == typeof(global::Speechify.V1FilesGetParametersKind))
if (typeToConvert == typeof(global::Speechify.FileKind))
{
return new global::Speechify.JsonConverters.V1FilesGetParametersKindJsonConverter();
return new global::Speechify.JsonConverters.FileKindJsonConverter();
}

if (typeToConvert == typeof(global::Speechify.V1FilesGetParametersKind?))
if (typeToConvert == typeof(global::Speechify.FileKind?))
{
return new global::Speechify.JsonConverters.V1FilesGetParametersKindNullableJsonConverter();
return new global::Speechify.JsonConverters.FileKindNullableJsonConverter();
}

if (typeToConvert == typeof(global::Speechify.FileKind))
if (typeToConvert == typeof(global::Speechify.V1FilesGetParametersKind))
{
return new global::Speechify.JsonConverters.FileKindJsonConverter();
return new global::Speechify.JsonConverters.V1FilesGetParametersKindJsonConverter();
}

if (typeToConvert == typeof(global::Speechify.FileKind?))
if (typeToConvert == typeof(global::Speechify.V1FilesGetParametersKind?))
{
return new global::Speechify.JsonConverters.FileKindNullableJsonConverter();
return new global::Speechify.JsonConverters.V1FilesGetParametersKindNullableJsonConverter();
}

if (typeToConvert == typeof(global::Speechify.V1FilesPostRequestBodyContentMultipartFormDataSchemaKind))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,62 @@ public partial interface IRunsClient
/// a long-running agent instead of polling it.<br/>
/// Holds the connection open and tails the run's journal: a<br/>
/// `run.step.added` event per step (its `data` is a RunStep object, the<br/>
/// same shape List Run Steps returns), a `run.status.changed` event when<br/>
/// the run's status moves, and a terminal `run.ended` event carrying the<br/>
/// final status and, when the run stopped short, its<br/>
/// `incomplete_reason`. Consumers must ignore unknown event types.<br/>
/// same shape List Run Steps returns), a `run.reply.delta` event for each<br/>
/// piece of text the agent writes, as it writes it, a<br/>
/// `run.status.changed` event when the run's status moves, and a terminal<br/>
/// `run.ended` event carrying the final status and, when the run stopped<br/>
/// short, its `incomplete_reason`. Consumers must ignore unknown event<br/>
/// types.<br/>
/// A picture or chart the agent makes arrives before the run ends: the<br/>
/// `observation` step for the tool call that made it carries the file<br/>
/// under `files`, so a client can show it the moment that step is<br/>
/// delivered. `run.ended` lists every file the run produced.<br/>
/// A run waiting on a human approval is not terminal: the stream reports<br/>
/// `requires_action` and keeps tailing, so the client learns it has<br/>
/// something to decide.<br/>
/// ## The reply arrives as it is written<br/>
/// `run.reply.delta` carries the agent's text piece by piece, so a chat<br/>
/// built on runs shows the answer forming instead of a spinner. Each<br/>
/// piece names the journal position it is written at (`seq`) and how<br/>
/// many characters of that position's text precede it (`offset`). Keep<br/>
/// one buffer per `seq`: append a piece whose `offset` equals what you<br/>
/// hold, and on any other `offset` cut the buffer to it first (that only<br/>
/// happens after a step was re-executed, and means the earlier text is<br/>
/// void). Text is counted in Unicode code points.<br/>
/// Which text a buffer turns out to be is settled by the event that<br/>
/// closes it. A `run.step.added` at the same `seq` closes it as that<br/>
/// step's `content` - the plan of a tool call, which the agent wrote<br/>
/// before deciding to act - and the next piece starts a new buffer at a<br/>
/// later `seq`. `run.ended` closes the open buffer as the reply, and its<br/>
/// `output.reply` is the authoritative copy: replace the buffer with it.<br/>
/// A `run.ended` with no `output` (the run failed, was cancelled, or<br/>
/// stopped short) means the open buffer was abandoned mid-sentence -<br/>
/// show it as such or drop it; it is not an answer. A run parked in<br/>
/// `requires_action` never leaves a buffer open, because the text it<br/>
/// wrote before parking lands as the plan step first. A client that<br/>
/// never subscribes to `run.reply.delta` sees exactly the stream it saw<br/>
/// before the event existed. An agent on a custom LLM endpoint answers<br/>
/// whole, with no pieces before the step lands.<br/>
/// Following a run costs nothing beyond the run: the stream is not<br/>
/// metered, and its read load is a few small queries per second per<br/>
/// subscriber, a little more while the answer is being written.<br/>
/// ## The stream is expected to reconnect<br/>
/// **The server closes the connection after 4 minutes whether or not the<br/>
/// run has settled**, so a long run spans several connections. Only<br/>
/// `run.ended` means the run is over - a closed socket does not. The<br/>
/// response opens with `retry: 2000`, so a browser `EventSource`<br/>
/// reconnects on its own; a hand-rolled client must do the same.<br/>
/// Resume with the standard `Last-Event-ID` header. Step events carry<br/>
/// their `seq` as the event id, so a reconnect continues exactly where it<br/>
/// left off; status events carry no id, and an absent or unparseable<br/>
/// `Last-Event-ID` replays the journal from the beginning rather than<br/>
/// skipping it. On every connection, including a resume, the server emits<br/>
/// one `run.status.changed` carrying the run's current status before it<br/>
/// starts tailing. A `: keepalive` comment arrives every 15 seconds so an<br/>
/// intermediary does not time the connection out while the agent is<br/>
/// thinking.<br/>
/// their `seq` as the event id; reply pieces carry the seq of the last<br/>
/// step plus the position reached in the text being written, so a<br/>
/// reconnect continues exactly where it left off and never replays text<br/>
/// the client already rendered. Status events carry no id, and an absent<br/>
/// or unparseable `Last-Event-ID` replays the journal from the beginning<br/>
/// rather than skipping it. On every connection, including a resume, the<br/>
/// server emits one `run.status.changed` carrying the run's current<br/>
/// status before it starts tailing. A `: keepalive` comment arrives every<br/>
/// 15 seconds so an intermediary does not time the connection out while<br/>
/// the agent is thinking.<br/>
/// Same read access as List Run Steps, and the same<br/>
/// `402 durable_runs_not_in_plan` on a workspace without the grant.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,34 @@ public class AgentRunStreamEventJsonConverter : global::System.Text.Json.Seriali
throw new global::System.InvalidOperationException($"Cannot get type info for {nameof(global::Speechify.AgentRunStreamEventVariant1)}");
runStepAdded = global::System.Text.Json.JsonSerializer.Deserialize(ref reader, typeInfo);
}
global::Speechify.AgentRunStreamEventVariant2? runStatusChanged = default;
if (discriminator?.Type == global::Speechify.AgentRunStreamEventDiscriminatorType.RunStatusChanged)
global::Speechify.AgentRunStreamEventVariant2? runReplyDelta = default;
if (discriminator?.Type == global::Speechify.AgentRunStreamEventDiscriminatorType.RunReplyDelta)
{
var typeInfo = typeInfoResolver.GetTypeInfo(typeof(global::Speechify.AgentRunStreamEventVariant2), options) as global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::Speechify.AgentRunStreamEventVariant2> ??
throw new global::System.InvalidOperationException($"Cannot get type info for {nameof(global::Speechify.AgentRunStreamEventVariant2)}");
runStatusChanged = global::System.Text.Json.JsonSerializer.Deserialize(ref reader, typeInfo);
runReplyDelta = global::System.Text.Json.JsonSerializer.Deserialize(ref reader, typeInfo);
}
global::Speechify.AgentRunStreamEventVariant3? runEnded = default;
if (discriminator?.Type == global::Speechify.AgentRunStreamEventDiscriminatorType.RunEnded)
global::Speechify.AgentRunStreamEventVariant3? runStatusChanged = default;
if (discriminator?.Type == global::Speechify.AgentRunStreamEventDiscriminatorType.RunStatusChanged)
{
var typeInfo = typeInfoResolver.GetTypeInfo(typeof(global::Speechify.AgentRunStreamEventVariant3), options) as global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::Speechify.AgentRunStreamEventVariant3> ??
throw new global::System.InvalidOperationException($"Cannot get type info for {nameof(global::Speechify.AgentRunStreamEventVariant3)}");
runStatusChanged = global::System.Text.Json.JsonSerializer.Deserialize(ref reader, typeInfo);
}
global::Speechify.AgentRunStreamEventVariant4? runEnded = default;
if (discriminator?.Type == global::Speechify.AgentRunStreamEventDiscriminatorType.RunEnded)
{
var typeInfo = typeInfoResolver.GetTypeInfo(typeof(global::Speechify.AgentRunStreamEventVariant4), options) as global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::Speechify.AgentRunStreamEventVariant4> ??
throw new global::System.InvalidOperationException($"Cannot get type info for {nameof(global::Speechify.AgentRunStreamEventVariant4)}");
runEnded = global::System.Text.Json.JsonSerializer.Deserialize(ref reader, typeInfo);
}

var __value = new global::Speechify.AgentRunStreamEvent(
discriminator?.Type,
runStepAdded,

runReplyDelta,

runStatusChanged,

runEnded
Expand All @@ -70,16 +79,22 @@ public override void Write(
throw new global::System.InvalidOperationException($"Cannot get type info for {typeof(global::Speechify.AgentRunStreamEventVariant1).Name}");
global::System.Text.Json.JsonSerializer.Serialize(writer, value.RunStepAdded!, typeInfo);
}
else if (value.IsRunStatusChanged)
else if (value.IsRunReplyDelta)
{
var typeInfo = typeInfoResolver.GetTypeInfo(typeof(global::Speechify.AgentRunStreamEventVariant2), options) as global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::Speechify.AgentRunStreamEventVariant2?> ??
throw new global::System.InvalidOperationException($"Cannot get type info for {typeof(global::Speechify.AgentRunStreamEventVariant2).Name}");
global::System.Text.Json.JsonSerializer.Serialize(writer, value.RunStatusChanged!, typeInfo);
global::System.Text.Json.JsonSerializer.Serialize(writer, value.RunReplyDelta!, typeInfo);
}
else if (value.IsRunEnded)
else if (value.IsRunStatusChanged)
{
var typeInfo = typeInfoResolver.GetTypeInfo(typeof(global::Speechify.AgentRunStreamEventVariant3), options) as global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::Speechify.AgentRunStreamEventVariant3?> ??
throw new global::System.InvalidOperationException($"Cannot get type info for {typeof(global::Speechify.AgentRunStreamEventVariant3).Name}");
global::System.Text.Json.JsonSerializer.Serialize(writer, value.RunStatusChanged!, typeInfo);
}
else if (value.IsRunEnded)
{
var typeInfo = typeInfoResolver.GetTypeInfo(typeof(global::Speechify.AgentRunStreamEventVariant4), options) as global::System.Text.Json.Serialization.Metadata.JsonTypeInfo<global::Speechify.AgentRunStreamEventVariant4?> ??
throw new global::System.InvalidOperationException($"Cannot get type info for {typeof(global::Speechify.AgentRunStreamEventVariant4).Name}");
global::System.Text.Json.JsonSerializer.Serialize(writer, value.RunEnded!, typeInfo);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#nullable enable

namespace Speechify.JsonConverters
{
/// <inheritdoc />
public sealed class AgentRunStreamEventVariant4TypeJsonConverter : global::System.Text.Json.Serialization.JsonConverter<global::Speechify.AgentRunStreamEventVariant4Type>
{
/// <inheritdoc />
public override global::Speechify.AgentRunStreamEventVariant4Type Read(
ref global::System.Text.Json.Utf8JsonReader reader,
global::System.Type typeToConvert,
global::System.Text.Json.JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case global::System.Text.Json.JsonTokenType.String:
{
var stringValue = reader.GetString();
if (stringValue != null)
{
return global::Speechify.AgentRunStreamEventVariant4TypeExtensions.ToEnum(stringValue) ?? default;
}

break;
}
case global::System.Text.Json.JsonTokenType.Number:
{
var numValue = reader.GetInt32();
return (global::Speechify.AgentRunStreamEventVariant4Type)numValue;
}
case global::System.Text.Json.JsonTokenType.Null:
{
return default(global::Speechify.AgentRunStreamEventVariant4Type);
}
default:
throw new global::System.ArgumentOutOfRangeException(nameof(reader));
}

return default;
}

/// <inheritdoc />
public override void Write(
global::System.Text.Json.Utf8JsonWriter writer,
global::Speechify.AgentRunStreamEventVariant4Type value,
global::System.Text.Json.JsonSerializerOptions options)
{
writer = writer ?? throw new global::System.ArgumentNullException(nameof(writer));

writer.WriteStringValue(global::Speechify.AgentRunStreamEventVariant4TypeExtensions.ToValueString(value));
}
}
}
Loading