mirror of
https://github.com/hanzoai/go-openai-realtime.git
synced 2026-09-30 21:54:42 +00:00
feat: optimize types & add full comments
This commit is contained in:
@@ -64,24 +64,28 @@ type connectOption struct {
|
||||
|
||||
type ConnectOption func(*connectOption)
|
||||
|
||||
// WithModel sets the model to use for the connection.
|
||||
func WithModel(model string) ConnectOption {
|
||||
return func(opts *connectOption) {
|
||||
opts.model = model
|
||||
}
|
||||
}
|
||||
|
||||
// WithDialOptions sets the dial options for the connection.
|
||||
func WithDialOptions(dialOptions *websocket.DialOptions) ConnectOption {
|
||||
return func(opts *connectOption) {
|
||||
opts.dialOptions = dialOptions
|
||||
}
|
||||
}
|
||||
|
||||
// WithReadLimit sets the read limit for the connection.
|
||||
func WithReadLimit(limit int64) ConnectOption {
|
||||
return func(opts *connectOption) {
|
||||
opts.readLimit = limit
|
||||
}
|
||||
}
|
||||
|
||||
// Connect connects to the OpenAI Realtime API.
|
||||
func (c *Client) Connect(ctx context.Context, opts ...ConnectOption) (*Conn, error) {
|
||||
connectOpts := connectOption{
|
||||
model: GPT4oRealtimePreview,
|
||||
|
||||
+83
-24
@@ -2,6 +2,7 @@ package openairt
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// ClientEventType is the type of client event. See https://platform.openai.com/docs/guides/realtime/client-events
|
||||
type ClientEventType string
|
||||
|
||||
const (
|
||||
@@ -16,30 +17,48 @@ const (
|
||||
ClientEventTypeResponseCancel ClientEventType = "response.cancel"
|
||||
)
|
||||
|
||||
// ClientEvent is the interface for client event.
|
||||
type ClientEvent interface {
|
||||
ClientEventType() ClientEventType
|
||||
}
|
||||
|
||||
// EventBase is the base struct for all client events.
|
||||
type EventBase struct {
|
||||
// Optional client-generated ID used to identify this event.
|
||||
EventID string `json:"event_id,omitempty"`
|
||||
}
|
||||
|
||||
type ClientSession struct {
|
||||
Modalities []Modality `json:"modalities,omitempty"`
|
||||
Instructions string `json:"instructions,omitempty"`
|
||||
Voice Voice `json:"voice,omitempty"`
|
||||
InputAudioFormat AudioFormat `json:"input_audio_format,omitempty"`
|
||||
OutputAudioFormat AudioFormat `json:"output_audio_format,omitempty"`
|
||||
// The set of modalities the model can respond with. To disable audio, set this to ["text"].
|
||||
Modalities []Modality `json:"modalities,omitempty"`
|
||||
// The default system instructions prepended to model calls.
|
||||
Instructions string `json:"instructions,omitempty"`
|
||||
// The voice the model uses to respond - one of alloy, echo, or shimmer. Cannot be changed once the model has responded with audio at least once.
|
||||
Voice Voice `json:"voice,omitempty"`
|
||||
// The format of input audio. Options are "pcm16", "g711_ulaw", or "g711_alaw".
|
||||
InputAudioFormat AudioFormat `json:"input_audio_format,omitempty"`
|
||||
// The format of output audio. Options are "pcm16", "g711_ulaw", or "g711_alaw".
|
||||
OutputAudioFormat AudioFormat `json:"output_audio_format,omitempty"`
|
||||
// Configuration for input audio transcription. Can be set to `nil` to turn off.
|
||||
InputAudioTranscription *InputAudioTranscription `json:"input_audio_transcription,omitempty"`
|
||||
TurnDetection *TurnDetection `json:"turn_detection,omitempty"`
|
||||
Tools []Tool `json:"tools,omitempty"`
|
||||
ToolChoice ToolChoiceInterface `json:"tool_choice,omitempty"`
|
||||
Temperature *float32 `json:"temperature,omitempty"`
|
||||
MaxOutputTokens int `json:"max_output_tokens,omitempty"`
|
||||
// Configuration for turn detection. Can be set to `nil` to turn off.
|
||||
TurnDetection *TurnDetection `json:"turn_detection,omitempty"`
|
||||
// Tools (functions) available to the model.
|
||||
Tools []Tool `json:"tools,omitempty"`
|
||||
// How the model chooses tools. Options are "auto", "none", "required", or specify a function.
|
||||
ToolChoice ToolChoiceInterface `json:"tool_choice,omitempty"`
|
||||
// Sampling temperature for the model.
|
||||
Temperature *float32 `json:"temperature,omitempty"`
|
||||
// Maximum number of output tokens for a single assistant response, inclusive of tool calls. Provide an integer between 1 and 4096 to limit output tokens, or "inf" for the maximum available tokens for a given model. Defaults to "inf".
|
||||
MaxOutputTokens IntOrInf `json:"max_output_tokens,omitempty"`
|
||||
}
|
||||
|
||||
// SessionUpdateEvent is the event for session update.
|
||||
// Send this event to update the session’s default configuration.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-client-events/session/update
|
||||
type SessionUpdateEvent struct {
|
||||
EventBase
|
||||
// Session configuration to update.
|
||||
Session ClientSession `json:"session"`
|
||||
}
|
||||
|
||||
@@ -59,9 +78,12 @@ func (m SessionUpdateEvent) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
// InputAudioBufferAppendEvent is the event for input audio buffer append.
|
||||
// Send this event to append audio bytes to the input audio buffer.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-client-events/input_audio_buffer/append
|
||||
type InputAudioBufferAppendEvent struct {
|
||||
EventBase
|
||||
Audio string `json:"audio"`
|
||||
Audio string `json:"audio"` // Base64-encoded audio bytes.
|
||||
}
|
||||
|
||||
func (m InputAudioBufferAppendEvent) ClientEventType() ClientEventType {
|
||||
@@ -80,6 +102,9 @@ func (m InputAudioBufferAppendEvent) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
// InputAudioBufferCommitEvent is the event for input audio buffer commit.
|
||||
// Send this event to commit audio bytes to a user message.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-client-events/input_audio_buffer/commit
|
||||
type InputAudioBufferCommitEvent struct {
|
||||
EventBase
|
||||
}
|
||||
@@ -100,6 +125,9 @@ func (m InputAudioBufferCommitEvent) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
// InputAudioBufferClearEvent is the event for input audio buffer clear.
|
||||
// Send this event to clear the audio bytes in the buffer.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-client-events/input_audio_buffer/clear
|
||||
type InputAudioBufferClearEvent struct {
|
||||
EventBase
|
||||
}
|
||||
@@ -120,10 +148,15 @@ func (m InputAudioBufferClearEvent) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
// ConversationItemCreateEvent is the event for conversation item create.
|
||||
// Send this event when adding an item to the conversation.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-client-events/conversation/item/create
|
||||
type ConversationItemCreateEvent struct {
|
||||
EventBase
|
||||
PreviousItemID string `json:"previous_item_id,omitempty"`
|
||||
Item MessageItem `json:"item"`
|
||||
// The ID of the preceding item after which the new item will be inserted.
|
||||
PreviousItemID string `json:"previous_item_id,omitempty"`
|
||||
// The item to add to the conversation.
|
||||
Item MessageItem `json:"item"`
|
||||
}
|
||||
|
||||
func (m ConversationItemCreateEvent) ClientEventType() ClientEventType {
|
||||
@@ -142,11 +175,17 @@ func (m ConversationItemCreateEvent) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
// ConversationItemTruncateEvent is the event for conversation item truncate.
|
||||
// Send this event when you want to truncate a previous assistant message’s audio.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-client-events/conversation/item/truncate
|
||||
type ConversationItemTruncateEvent struct {
|
||||
EventBase
|
||||
ItemID string `json:"item_id"`
|
||||
ContentIndex int `json:"content_index"`
|
||||
AudioEndMs int `json:"audio_end_ms"`
|
||||
// The ID of the assistant message item to truncate.
|
||||
ItemID string `json:"item_id"`
|
||||
// The index of the content part to truncate.
|
||||
ContentIndex int `json:"content_index"`
|
||||
// Inclusive duration up to which audio is truncated, in milliseconds.
|
||||
AudioEndMs int `json:"audio_end_ms"`
|
||||
}
|
||||
|
||||
func (m ConversationItemTruncateEvent) ClientEventType() ClientEventType {
|
||||
@@ -165,8 +204,12 @@ func (m ConversationItemTruncateEvent) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
// ConversationItemDeleteEvent is the event for conversation item delete.
|
||||
// Send this event when you want to remove any item from the conversation history.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-client-events/conversation/item/delete
|
||||
type ConversationItemDeleteEvent struct {
|
||||
EventBase
|
||||
// The ID of the item to delete.
|
||||
ItemID string `json:"item_id"`
|
||||
}
|
||||
|
||||
@@ -187,18 +230,30 @@ func (m ConversationItemDeleteEvent) MarshalJSON() ([]byte, error) {
|
||||
}
|
||||
|
||||
type ResponseCreateParams struct {
|
||||
Modalities []Modality `json:"modalities,omitempty"`
|
||||
Instructions string `json:"instructions,omitempty"`
|
||||
Voice Voice `json:"voice,omitempty"`
|
||||
OutputAudioFormat AudioFormat `json:"output_audio_format,omitempty"`
|
||||
Tools []Tool `json:"tools,omitempty"`
|
||||
ToolChoice ToolChoiceInterface `json:"tool_choice,omitempty"`
|
||||
Temperature *float32 `json:"temperature,omitempty"`
|
||||
MaxOutputTokens int `json:"max_output_tokens,omitempty"`
|
||||
// The modalities for the response.
|
||||
Modalities []Modality `json:"modalities,omitempty"`
|
||||
// Instructions for the model.
|
||||
Instructions string `json:"instructions,omitempty"`
|
||||
// The voice the model uses to respond - one of alloy, echo, or shimmer.
|
||||
Voice Voice `json:"voice,omitempty"`
|
||||
// The format of output audio.
|
||||
OutputAudioFormat AudioFormat `json:"output_audio_format,omitempty"`
|
||||
// Tools (functions) available to the model.
|
||||
Tools []Tool `json:"tools,omitempty"`
|
||||
// How the model chooses tools.
|
||||
ToolChoice ToolChoiceInterface `json:"tool_choice,omitempty"`
|
||||
// Sampling temperature.
|
||||
Temperature *float32 `json:"temperature,omitempty"`
|
||||
// Maximum number of output tokens for a single assistant response, inclusive of tool calls. Provide an integer between 1 and 4096 to limit output tokens, or "inf" for the maximum available tokens for a given model. Defaults to "inf".
|
||||
MaxOutputTokens IntOrInf `json:"max_output_tokens,omitempty"`
|
||||
}
|
||||
|
||||
// ResponseCreateEvent is the event for response create.
|
||||
// Send this event to trigger a response generation.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-client-events/response/create
|
||||
type ResponseCreateEvent struct {
|
||||
EventBase
|
||||
// Configuration for the response.
|
||||
Response ResponseCreateParams `json:"response"`
|
||||
}
|
||||
|
||||
@@ -218,6 +273,9 @@ func (m ResponseCreateEvent) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
// ResponseCancelEvent is the event for response cancel.
|
||||
// Send this event to cancel an in-progress response.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-client-events/response/cancel
|
||||
type ResponseCancelEvent struct {
|
||||
EventBase
|
||||
}
|
||||
@@ -238,6 +296,7 @@ func (m ResponseCancelEvent) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
// MarshalClientEvent marshals the client event to JSON.
|
||||
func MarshalClientEvent(event ClientEvent) ([]byte, error) {
|
||||
return json.Marshal(event)
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ func TestSessionUpdateEvent(t *testing.T) {
|
||||
},
|
||||
},
|
||||
Temperature: &temperature,
|
||||
MaxOutputTokens: 100,
|
||||
MaxOutputTokens: openairt.Int(100),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ func TestSessionUpdateEventSimple(t *testing.T) {
|
||||
Tools: nil,
|
||||
ToolChoice: nil,
|
||||
Temperature: &temperature,
|
||||
MaxOutputTokens: 100,
|
||||
MaxOutputTokens: openairt.Int(100),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -313,7 +313,7 @@ func TestResponseCreateEvent(t *testing.T) {
|
||||
Tools: nil,
|
||||
ToolChoice: openairt.ToolChoiceAuto,
|
||||
Temperature: nil,
|
||||
MaxOutputTokens: 100,
|
||||
MaxOutputTokens: openairt.Int(100),
|
||||
},
|
||||
}
|
||||
data, err := json.MarshalIndent(message, "", "\t")
|
||||
@@ -335,9 +335,10 @@ func TestResponseCreateEvent(t *testing.T) {
|
||||
assert.JSONEq(t, expected, string(data))
|
||||
|
||||
message.EventBase.EventID = "test-id"
|
||||
message.Response.MaxOutputTokens = openairt.Inf()
|
||||
data, err = json.Marshal(message)
|
||||
assert.NoError(t, err)
|
||||
expected = `{"event_id":"test-id","response":{"modalities":["text","audio"],"instructions":"test-instructions","voice":"alloy","output_audio_format":"g711-ulaw","tool_choice":"auto","max_output_tokens":100},"type":"response.create"}`
|
||||
expected = `{"event_id":"test-id","response":{"modalities":["text","audio"],"instructions":"test-instructions","voice":"alloy","output_audio_format":"g711-ulaw","tool_choice":"auto","max_output_tokens":"inf"},"type":"response.create"}`
|
||||
assert.JSONEq(t, expected, string(data))
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +1,36 @@
|
||||
package openairt
|
||||
|
||||
// APIType is the type of API.
|
||||
type APIType string
|
||||
|
||||
const (
|
||||
// APITypeOpenAI is the type of API for OpenAI.
|
||||
APITypeOpenAI APIType = "OPEN_AI"
|
||||
APITypeAzure APIType = "AZURE"
|
||||
// APITypeAzure is the type of API for Azure.
|
||||
APITypeAzure APIType = "AZURE"
|
||||
)
|
||||
|
||||
const (
|
||||
// openaiAPIURLv1 is the base URL for the OpenAI Realtime API.
|
||||
openaiAPIURLv1 = "wss://api.openai.com/v1/realtime"
|
||||
)
|
||||
|
||||
const (
|
||||
// azureAPIVersion20241001Preview is the API version for Azure.
|
||||
azureAPIVersion20241001Preview = "2024-10-01-preview"
|
||||
)
|
||||
|
||||
// ClientConfig is the configuration for the client.
|
||||
type ClientConfig struct {
|
||||
authToken string
|
||||
|
||||
BaseURL string
|
||||
APIType APIType
|
||||
APIVersion string // required when APIType is APITypeAzure
|
||||
BaseURL string // Base URL for the API. Defaults to "wss://api.openai.com/v1/realtime"
|
||||
APIType APIType // API type. Defaults to APITypeOpenAI
|
||||
APIVersion string // required when APIType is APITypeAzure
|
||||
}
|
||||
|
||||
// DefaultConfig creates a new ClientConfig with the given auth token.
|
||||
// Defaults to using the OpenAI Realtime API.
|
||||
func DefaultConfig(authToken string) ClientConfig {
|
||||
return ClientConfig{
|
||||
authToken: authToken,
|
||||
@@ -31,6 +39,8 @@ func DefaultConfig(authToken string) ClientConfig {
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultAzureConfig creates a new ClientConfig with the given auth token and base URL.
|
||||
// Defaults to using the Azure Realtime API.
|
||||
func DefaultAzureConfig(apiKey, baseURL string) ClientConfig {
|
||||
return ClientConfig{
|
||||
authToken: apiKey,
|
||||
@@ -40,6 +50,7 @@ func DefaultAzureConfig(apiKey, baseURL string) ClientConfig {
|
||||
}
|
||||
}
|
||||
|
||||
func (ClientConfig) String() string {
|
||||
// String returns a string representation of the ClientConfig.
|
||||
func (c ClientConfig) String() string {
|
||||
return "<OpenAI Realtime API ClientConfig>"
|
||||
}
|
||||
|
||||
@@ -11,14 +11,17 @@ import (
|
||||
|
||||
type ServerEventHandler func(ctx context.Context, event ServerEvent)
|
||||
|
||||
// Conn is a connection to the OpenAI Realtime API.
|
||||
type Conn struct {
|
||||
conn *websocket.Conn
|
||||
}
|
||||
|
||||
// Close closes the connection.
|
||||
func (c *Conn) Close() error {
|
||||
return c.conn.Close(websocket.StatusNormalClosure, "")
|
||||
}
|
||||
|
||||
// SendMessage sends a client event to the server.
|
||||
func (c *Conn) SendMessage(ctx context.Context, msg ClientEvent) error {
|
||||
data, err := MarshalClientEvent(msg)
|
||||
if err != nil {
|
||||
@@ -27,6 +30,7 @@ func (c *Conn) SendMessage(ctx context.Context, msg ClientEvent) error {
|
||||
return c.conn.Write(ctx, websocket.MessageText, data)
|
||||
}
|
||||
|
||||
// ReadMessage reads a server event from the server.
|
||||
func (c *Conn) ReadMessage(ctx context.Context) (ServerEvent, error) {
|
||||
messageType, data, err := c.conn.Read(ctx)
|
||||
if err != nil {
|
||||
@@ -42,15 +46,20 @@ func (c *Conn) ReadMessage(ctx context.Context) (ServerEvent, error) {
|
||||
return event, nil
|
||||
}
|
||||
|
||||
// ConnHandler is a handler for a connection to the OpenAI Realtime API.
|
||||
// It reads messages from the server in a standalone goroutine and calls the registered handlers.
|
||||
// It is the responsibility of the caller to call Start and Stop.
|
||||
// The handlers are called in the order they are registered.
|
||||
// Users should not call ReadMessage directly when using ConnHandler.
|
||||
type ConnHandler struct {
|
||||
ctx context.Context
|
||||
conn *Conn
|
||||
handlers []ServerEventHandler
|
||||
cancel context.CancelFunc
|
||||
wg sync.WaitGroup
|
||||
err error
|
||||
}
|
||||
|
||||
// NewConnHandler creates a new ConnHandler with the given context and connection.
|
||||
func NewConnHandler(ctx context.Context, conn *Conn, handlers ...ServerEventHandler) *ConnHandler {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
return &ConnHandler{
|
||||
@@ -61,11 +70,12 @@ func NewConnHandler(ctx context.Context, conn *Conn, handlers ...ServerEventHand
|
||||
}
|
||||
}
|
||||
|
||||
// Start starts the ConnHandler.
|
||||
func (c *ConnHandler) Start() {
|
||||
c.wg.Add(1)
|
||||
go func() {
|
||||
defer c.wg.Done()
|
||||
c.err = c.run()
|
||||
c.run()
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -88,11 +98,8 @@ func (c *ConnHandler) run() error {
|
||||
}
|
||||
}
|
||||
|
||||
// Stop stops the ConnHandler.
|
||||
func (c *ConnHandler) Stop() {
|
||||
c.cancel()
|
||||
c.wg.Wait()
|
||||
}
|
||||
|
||||
func (c *ConnHandler) Err() error {
|
||||
return c.err
|
||||
}
|
||||
|
||||
@@ -52,12 +52,7 @@ func main() {
|
||||
|
||||
connHandler := openairt.NewConnHandler(ctx, conn, responseDeltaHandler, responseHandler)
|
||||
connHandler.Start()
|
||||
defer func() {
|
||||
connHandler.Stop()
|
||||
if err := connHandler.Err(); err != nil {
|
||||
log.Printf("connHandler.Err(): %v", err)
|
||||
}
|
||||
}()
|
||||
defer connHandler.Stop()
|
||||
|
||||
err = conn.SendMessage(ctx, &openairt.SessionUpdateEvent{
|
||||
Session: openairt.ClientSession{
|
||||
@@ -93,7 +88,7 @@ func main() {
|
||||
conn.SendMessage(ctx, &openairt.ResponseCreateEvent{
|
||||
Response: openairt.ResponseCreateParams{
|
||||
Modalities: []openairt.Modality{openairt.ModalityText},
|
||||
MaxOutputTokens: 100,
|
||||
MaxOutputTokens: openairt.Int(100),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -121,12 +121,7 @@ func main() {
|
||||
|
||||
connHandler := openairt.NewConnHandler(ctx, conn, allHandler, responseDeltaHandler, responseHandler, audioResponseHandler)
|
||||
connHandler.Start()
|
||||
defer func() {
|
||||
connHandler.Stop()
|
||||
if err := connHandler.Err(); err != nil {
|
||||
log.Printf("connHandler.Err(): %v", err)
|
||||
}
|
||||
}()
|
||||
defer connHandler.Stop()
|
||||
|
||||
err = conn.SendMessage(ctx, &openairt.SessionUpdateEvent{
|
||||
Session: openairt.ClientSession{
|
||||
@@ -164,7 +159,7 @@ func main() {
|
||||
conn.SendMessage(ctx, &openairt.ResponseCreateEvent{
|
||||
Response: openairt.ResponseCreateParams{
|
||||
Modalities: []openairt.Modality{openairt.ModalityText, openairt.ModalityAudio},
|
||||
MaxOutputTokens: 4000,
|
||||
MaxOutputTokens: openairt.Int(4000),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package openairt
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// IntOrInf is a type that can be either an int or "inf".
|
||||
type IntOrInf struct {
|
||||
value int
|
||||
inf bool
|
||||
}
|
||||
|
||||
// Inf returns an IntOrInf with the value "inf".
|
||||
func Inf() IntOrInf {
|
||||
return IntOrInf{
|
||||
inf: true,
|
||||
}
|
||||
}
|
||||
|
||||
// Int returns an IntOrInf with the given value.
|
||||
func Int(value int) IntOrInf {
|
||||
return IntOrInf{
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
||||
// IsInf returns true if the value is "inf".
|
||||
func (m IntOrInf) IsInf() bool {
|
||||
return m.inf
|
||||
}
|
||||
|
||||
// Value returns the value as an int.
|
||||
func (m IntOrInf) Value() int {
|
||||
return m.value
|
||||
}
|
||||
|
||||
// MarshalJSON marshals the IntOrInf to JSON.
|
||||
func (m IntOrInf) MarshalJSON() ([]byte, error) {
|
||||
if m.inf {
|
||||
return []byte("\"inf\""), nil
|
||||
}
|
||||
return json.Marshal(m.value)
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals the IntOrInf from JSON.
|
||||
func (m *IntOrInf) UnmarshalJSON(data []byte) error {
|
||||
if string(data) == "\"inf\"" {
|
||||
m.inf = true
|
||||
return nil
|
||||
}
|
||||
if len(data) == 0 {
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal(data, &m.value)
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package openairt_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
openairt "github.com/WqyJh/go-openai-realtime"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIntOrInfMarshalJSON(t *testing.T) {
|
||||
v := openairt.Int(10)
|
||||
assert.Equal(t, 10, v.Value())
|
||||
assert.False(t, v.IsInf())
|
||||
|
||||
b, err := json.Marshal(v)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []byte("10"), b)
|
||||
|
||||
v = openairt.Inf()
|
||||
assert.Equal(t, 0, v.Value())
|
||||
assert.True(t, v.IsInf())
|
||||
|
||||
v = openairt.Inf()
|
||||
b, err = json.Marshal(v)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, []byte("\"inf\""), b)
|
||||
}
|
||||
+174
-48
@@ -38,59 +38,97 @@ const (
|
||||
ServerEventTypeRateLimitsUpdated ServerEventType = "rate_limits.updated"
|
||||
)
|
||||
|
||||
// ServerEvent is the interface for server events.
|
||||
type ServerEvent interface {
|
||||
ServerEventType() ServerEventType
|
||||
}
|
||||
|
||||
// ServerEventBase is the base struct for all server events.
|
||||
type ServerEventBase struct {
|
||||
EventID string `json:"event_id,omitempty"`
|
||||
Type ServerEventType `json:"type"`
|
||||
// The unique ID of the server event.
|
||||
EventID string `json:"event_id,omitempty"`
|
||||
// The type of the server event.
|
||||
Type ServerEventType `json:"type"`
|
||||
}
|
||||
|
||||
func (m ServerEventBase) ServerEventType() ServerEventType {
|
||||
return m.Type
|
||||
}
|
||||
|
||||
// ErrorEvent is the event for error.
|
||||
// Returned when an error occurs.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/error
|
||||
type ErrorEvent struct {
|
||||
ServerEventBase
|
||||
// Details of the error.
|
||||
Error Error `json:"error"`
|
||||
}
|
||||
|
||||
// SessionCreatedEvent is the event for session created.
|
||||
// Returned when a session is created. Emitted automatically when a new connection is established.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/session/created
|
||||
type SessionCreatedEvent struct {
|
||||
ServerEventBase
|
||||
// The session resource.
|
||||
Session ServerSession `json:"session"`
|
||||
}
|
||||
|
||||
// SessionUpdatedEvent is the event for session updated.
|
||||
// Returned when a session is updated.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/session/updated
|
||||
type SessionUpdatedEvent struct {
|
||||
ServerEventBase
|
||||
// The updated session resource.
|
||||
Session ServerSession `json:"session"`
|
||||
}
|
||||
|
||||
// ConversationCreatedEvent is the event for conversation created.
|
||||
// Returned when a conversation is created. Emitted right after session creation.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/conversation/created
|
||||
type ConversationCreatedEvent struct {
|
||||
ServerEventBase
|
||||
// The conversation resource.
|
||||
Conversation Conversation `json:"conversation"`
|
||||
}
|
||||
|
||||
// InputAudioBufferCommittedEvent is the event for input audio buffer committed.
|
||||
// Returned when an input audio buffer is committed, either by the client or automatically in server VAD mode.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/input_audio_buffer/committed
|
||||
type InputAudioBufferCommittedEvent struct {
|
||||
ServerEventBase
|
||||
// The ID of the preceding item after which the new item will be inserted.
|
||||
PreviousItemID string `json:"previous_item_id,omitempty"`
|
||||
ItemID string `json:"item_id"`
|
||||
// The ID of the user message item that will be created.
|
||||
ItemID string `json:"item_id"`
|
||||
}
|
||||
|
||||
// InputAudioBufferClearedEvent is the event for input audio buffer cleared.
|
||||
// Returned when the input audio buffer is cleared by the client.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/input_audio_buffer/cleared
|
||||
type InputAudioBufferClearedEvent struct {
|
||||
ServerEventBase
|
||||
}
|
||||
|
||||
// InputAudioBufferSpeechStartedEvent is the event for input audio buffer speech started.
|
||||
// Returned in server turn detection mode when speech is detected.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/input_audio_buffer/speech_started
|
||||
type InputAudioBufferSpeechStartedEvent struct {
|
||||
ServerEventBase
|
||||
AudioStartMs int64 `json:"audio_start_ms"` // Milliseconds since the session started when speech was detected.
|
||||
ItemID string `json:"item_id"`
|
||||
// Milliseconds since the session started when speech was detected.
|
||||
AudioStartMs int64 `json:"audio_start_ms"`
|
||||
// The ID of the user message item that will be created when speech stops.
|
||||
ItemID string `json:"item_id"`
|
||||
}
|
||||
|
||||
// InputAudioBufferSpeechStoppedEvent is the event for input audio buffer speech stopped.
|
||||
// Returned in server turn detection mode when speech stops.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/input_audio_buffer/speech_stopped
|
||||
type InputAudioBufferSpeechStoppedEvent struct {
|
||||
ServerEventBase
|
||||
AudioEndMs int64 `json:"audio_end_ms"` // Milliseconds since the session started when speech stopped.
|
||||
ItemID string `json:"item_id"`
|
||||
// Milliseconds since the session started when speech stopped.
|
||||
AudioEndMs int64 `json:"audio_end_ms"`
|
||||
// The ID of the user message item that will be created.
|
||||
ItemID string `json:"item_id"`
|
||||
}
|
||||
|
||||
type ConversationItemCreatedEvent struct {
|
||||
@@ -125,30 +163,53 @@ type ConversationItemDeletedEvent struct {
|
||||
ItemID string `json:"item_id"` // The ID of the item that was deleted.
|
||||
}
|
||||
|
||||
// ResponseCreatedEvent is the event for response created.
|
||||
// Returned when a new Response is created. The first event of response creation, where the response is in an initial state of "in_progress".
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/response/created
|
||||
type ResponseCreatedEvent struct {
|
||||
ServerEventBase
|
||||
// The response resource.
|
||||
Response Response `json:"response"`
|
||||
}
|
||||
|
||||
// ResponseDoneEvent is the event for response done.
|
||||
// Returned when a Response is done streaming. Always emitted, no matter the final state.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/response/done
|
||||
type ResponseDoneEvent struct {
|
||||
ServerEventBase
|
||||
// The response resource.
|
||||
Response Response `json:"response"`
|
||||
}
|
||||
|
||||
// ResponseOutputItemAddedEvent is the event for response output item added.
|
||||
// Returned when a new Item is created during response generation.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/response/output_item/added
|
||||
type ResponseOutputItemAddedEvent struct {
|
||||
ServerEventBase
|
||||
ResponseID string `json:"response_id"`
|
||||
OutputIndex int `json:"output_index"`
|
||||
Item ResponseMessageItem `json:"item"`
|
||||
// The ID of the response to which the item belongs.
|
||||
ResponseID string `json:"response_id"`
|
||||
// The index of the output item in the response.
|
||||
OutputIndex int `json:"output_index"`
|
||||
// The item that was added.
|
||||
Item ResponseMessageItem `json:"item"`
|
||||
}
|
||||
|
||||
// ResponseOutputItemDoneEvent is the event for response output item done.
|
||||
// Returned when an Item is done streaming. Also emitted when a Response is interrupted, incomplete, or cancelled.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/response/output_item/done
|
||||
type ResponseOutputItemDoneEvent struct {
|
||||
ServerEventBase
|
||||
ResponseID string `json:"response_id"`
|
||||
OutputIndex int `json:"output_index"`
|
||||
Item ResponseMessageItem `json:"item"`
|
||||
// The ID of the response to which the item belongs.
|
||||
ResponseID string `json:"response_id"`
|
||||
// The index of the output item in the response.
|
||||
OutputIndex int `json:"output_index"`
|
||||
// The completed item.
|
||||
Item ResponseMessageItem `json:"item"`
|
||||
}
|
||||
|
||||
// ResponseContentPartAddedEvent is the event for response content part added.
|
||||
// Returned when a new content part is added to an assistant message item during response generation.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/response/content_part/added
|
||||
type ResponseContentPartAddedEvent struct {
|
||||
ServerEventBase
|
||||
ResponseID string `json:"response_id"`
|
||||
@@ -158,15 +219,26 @@ type ResponseContentPartAddedEvent struct {
|
||||
Part MessageContentPart `json:"part"`
|
||||
}
|
||||
|
||||
// ResponseContentPartDoneEvent is the event for response content part done.
|
||||
// Returned when a content part is done streaming in an assistant message item. Also emitted when a Response is interrupted, incomplete, or cancelled.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/response/content_part/done
|
||||
type ResponseContentPartDoneEvent struct {
|
||||
ServerEventBase
|
||||
ResponseID string `json:"response_id"`
|
||||
ItemID string `json:"item_id"`
|
||||
OutputIndex int `json:"output_index"`
|
||||
ContentIndex int `json:"content_index"`
|
||||
Part MessageContentPart `json:"part"`
|
||||
// The ID of the response.
|
||||
ResponseID string `json:"response_id"`
|
||||
// The ID of the item to which the content part was added.
|
||||
ItemID string `json:"item_id"`
|
||||
// The index of the output item in the response.
|
||||
OutputIndex int `json:"output_index"`
|
||||
// The index of the content part in the item's content array.
|
||||
ContentIndex int `json:"content_index"`
|
||||
// The content part that was added.
|
||||
Part MessageContentPart `json:"part"`
|
||||
}
|
||||
|
||||
// ResponseTextDeltaEvent is the event for response text delta.
|
||||
// Returned when the text value of a "text" content part is updated.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/response/text/delta
|
||||
type ResponseTextDeltaEvent struct {
|
||||
ServerEventBase
|
||||
ResponseID string `json:"response_id"`
|
||||
@@ -176,6 +248,9 @@ type ResponseTextDeltaEvent struct {
|
||||
Delta string `json:"delta"`
|
||||
}
|
||||
|
||||
// ResponseTextDoneEvent is the event for response text done.
|
||||
// Returned when the text value of a "text" content part is done streaming. Also emitted when a Response is interrupted, incomplete, or cancelled.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/response/text/done
|
||||
type ResponseTextDoneEvent struct {
|
||||
ServerEventBase
|
||||
ResponseID string `json:"response_id"`
|
||||
@@ -185,65 +260,116 @@ type ResponseTextDoneEvent struct {
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
// ResponseAudioTranscriptDeltaEvent is the event for response audio transcript delta.
|
||||
// Returned when the model-generated transcription of audio output is updated.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/response/audio_transcript/delta
|
||||
type ResponseAudioTranscriptDeltaEvent struct {
|
||||
ServerEventBase
|
||||
ResponseID string `json:"response_id"`
|
||||
ItemID string `json:"item_id"`
|
||||
OutputIndex int `json:"output_index"`
|
||||
ContentIndex int `json:"content_index"`
|
||||
Delta string `json:"delta"`
|
||||
// The ID of the response.
|
||||
ResponseID string `json:"response_id"`
|
||||
// The ID of the item.
|
||||
ItemID string `json:"item_id"`
|
||||
// The index of the output item in the response.
|
||||
OutputIndex int `json:"output_index"`
|
||||
// The index of the content part in the item's content array.
|
||||
ContentIndex int `json:"content_index"`
|
||||
// The transcript delta.
|
||||
Delta string `json:"delta"`
|
||||
}
|
||||
|
||||
// ResponseAudioTranscriptDoneEvent is the event for response audio transcript done.
|
||||
// Returned when the model-generated transcription of audio output is done streaming. Also emitted when a Response is interrupted, incomplete, or cancelled.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/response/audio_transcript/done
|
||||
type ResponseAudioTranscriptDoneEvent struct {
|
||||
ServerEventBase
|
||||
ResponseID string `json:"response_id"`
|
||||
ItemID string `json:"item_id"`
|
||||
OutputIndex int `json:"output_index"`
|
||||
ContentIndex int `json:"content_index"`
|
||||
Transcript string `json:"transcript"`
|
||||
// The ID of the response.
|
||||
ResponseID string `json:"response_id"`
|
||||
// The ID of the item.
|
||||
ItemID string `json:"item_id"`
|
||||
// The index of the output item in the response.
|
||||
OutputIndex int `json:"output_index"`
|
||||
// The index of the content part in the item's content array.
|
||||
ContentIndex int `json:"content_index"`
|
||||
// The final transcript of the audio.
|
||||
Transcript string `json:"transcript"`
|
||||
}
|
||||
|
||||
// ResponseAudioDeltaEvent is the event for response audio delta.
|
||||
// Returned when the model-generated audio is updated.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/response/audio/delta
|
||||
type ResponseAudioDeltaEvent struct {
|
||||
ServerEventBase
|
||||
ResponseID string `json:"response_id"`
|
||||
ItemID string `json:"item_id"`
|
||||
OutputIndex int `json:"output_index"`
|
||||
ContentIndex int `json:"content_index"`
|
||||
Delta string `json:"delta"`
|
||||
// The ID of the response.
|
||||
ResponseID string `json:"response_id"`
|
||||
// The ID of the item.
|
||||
ItemID string `json:"item_id"`
|
||||
// The index of the output item in the response.
|
||||
OutputIndex int `json:"output_index"`
|
||||
// The index of the content part in the item's content array.
|
||||
ContentIndex int `json:"content_index"`
|
||||
// Base64-encoded audio data delta.
|
||||
Delta string `json:"delta"`
|
||||
}
|
||||
|
||||
// ResponseAudioDoneEvent is the event for response audio done.
|
||||
// Returned when the model-generated audio is done. Also emitted when a Response is interrupted, incomplete, or cancelled.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/response/audio/done
|
||||
type ResponseAudioDoneEvent struct {
|
||||
ServerEventBase
|
||||
ResponseID string `json:"response_id"`
|
||||
ItemID string `json:"item_id"`
|
||||
OutputIndex int `json:"output_index"`
|
||||
ContentIndex int `json:"content_index"`
|
||||
// The ID of the response.
|
||||
ResponseID string `json:"response_id"`
|
||||
// The ID of the item.
|
||||
ItemID string `json:"item_id"`
|
||||
// The index of the output item in the response.
|
||||
OutputIndex int `json:"output_index"`
|
||||
// The index of the content part in the item's content array.
|
||||
ContentIndex int `json:"content_index"`
|
||||
}
|
||||
|
||||
// ResponseFunctionCallArgumentsDeltaEvent is the event for response function call arguments delta.
|
||||
// Returned when the model-generated function call arguments are updated.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/response/function_call_arguments/delta
|
||||
type ResponseFunctionCallArgumentsDeltaEvent struct {
|
||||
ServerEventBase
|
||||
ResponseID string `json:"response_id"`
|
||||
ItemID string `json:"item_id"`
|
||||
OutputIndex int `json:"output_index"`
|
||||
CallID string `json:"call_id"`
|
||||
Delta string `json:"delta"`
|
||||
// The ID of the response.
|
||||
ResponseID string `json:"response_id"`
|
||||
// The ID of the item.
|
||||
ItemID string `json:"item_id"`
|
||||
// The index of the output item in the response.
|
||||
OutputIndex int `json:"output_index"`
|
||||
// The ID of the function call.
|
||||
CallID string `json:"call_id"`
|
||||
// The arguments delta as a JSON string.
|
||||
Delta string `json:"delta"`
|
||||
}
|
||||
|
||||
// ResponseFunctionCallArgumentsDoneEvent is the event for response function call arguments done.
|
||||
// Returned when the model-generated function call arguments are done streaming. Also emitted when a Response is interrupted, incomplete, or cancelled.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/response/function_call_arguments/done
|
||||
type ResponseFunctionCallArgumentsDoneEvent struct {
|
||||
ServerEventBase
|
||||
ResponseID string `json:"response_id"`
|
||||
ItemID string `json:"item_id"`
|
||||
OutputIndex int `json:"output_index"`
|
||||
CallID string `json:"call_id"`
|
||||
Name string `json:"name"`
|
||||
Arguments string `json:"arguments"`
|
||||
// The ID of the response.
|
||||
ResponseID string `json:"response_id"`
|
||||
// The ID of the item.
|
||||
ItemID string `json:"item_id"`
|
||||
// The index of the output item in the response.
|
||||
OutputIndex int `json:"output_index"`
|
||||
// The ID of the function call.
|
||||
CallID string `json:"call_id"`
|
||||
// The final arguments as a JSON string.
|
||||
Arguments string `json:"arguments"`
|
||||
}
|
||||
|
||||
// RateLimitsUpdatedEvent is the event for rate limits updated.
|
||||
// Emitted after every "response.done" event to indicate the updated rate limits.
|
||||
// See https://platform.openai.com/docs/api-reference/realtime-server-events/rate_limits/updated
|
||||
type RateLimitsUpdatedEvent struct {
|
||||
ServerEventBase
|
||||
// List of rate limit information.
|
||||
RateLimits []RateLimit `json:"rate_limits"`
|
||||
}
|
||||
|
||||
// UnmarshalServerEvent unmarshals the server event from the given JSON data.
|
||||
func UnmarshalServerEvent(data []byte) (ServerEvent, error) {
|
||||
var eventType struct {
|
||||
Type ServerEventType `json:"type"`
|
||||
|
||||
+33
-2
@@ -130,7 +130,7 @@ func TestSessionCreatedEvent(t *testing.T) {
|
||||
Tools: []openairt.Tool{},
|
||||
ToolChoice: openairt.ServerToolChoice{String: openairt.ToolChoiceAuto},
|
||||
Temperature: &temperature,
|
||||
MaxOutputTokens: 0,
|
||||
MaxOutputTokens: openairt.Int(0),
|
||||
},
|
||||
}
|
||||
actual, err := openairt.UnmarshalServerEvent([]byte(data))
|
||||
@@ -190,13 +190,44 @@ func TestSessionUpdatedEvent(t *testing.T) {
|
||||
Tools: []openairt.Tool{},
|
||||
ToolChoice: openairt.ServerToolChoice{String: openairt.ToolChoiceNone},
|
||||
Temperature: &temperature,
|
||||
MaxOutputTokens: 200,
|
||||
MaxOutputTokens: openairt.Int(200),
|
||||
},
|
||||
}
|
||||
actual, err := openairt.UnmarshalServerEvent([]byte(data))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, openairt.ServerEventTypeSessionUpdated, actual.ServerEventType())
|
||||
assert.Equal(t, expected, actual.(openairt.SessionUpdatedEvent))
|
||||
|
||||
data = `{
|
||||
"event_id": "event_5678",
|
||||
"type": "session.updated",
|
||||
"session": {
|
||||
"id": "sess_001",
|
||||
"object": "realtime.session",
|
||||
"model": "gpt-4o-realtime-preview-2024-10-01",
|
||||
"modalities": ["text"],
|
||||
"instructions": "New instructions",
|
||||
"voice": "alloy",
|
||||
"input_audio_format": "pcm16",
|
||||
"output_audio_format": "pcm16",
|
||||
"input_audio_transcription": {
|
||||
"enabled": true,
|
||||
"model": "whisper-1"
|
||||
},
|
||||
"turn_detection": {
|
||||
"type": "none"
|
||||
},
|
||||
"tools": [],
|
||||
"tool_choice": "none",
|
||||
"temperature": 0.7,
|
||||
"max_output_tokens": "inf"
|
||||
}
|
||||
}`
|
||||
expected.Session.MaxOutputTokens = openairt.Inf()
|
||||
actual, err = openairt.UnmarshalServerEvent([]byte(data))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, openairt.ServerEventTypeSessionUpdated, actual.ServerEventType())
|
||||
assert.Equal(t, expected, actual.(openairt.SessionUpdatedEvent))
|
||||
}
|
||||
|
||||
func TestConversationCreatedEvent(t *testing.T) {
|
||||
|
||||
@@ -37,10 +37,14 @@ const (
|
||||
)
|
||||
|
||||
type TurnDetection struct {
|
||||
Type TurnDetectionType `json:"type"`
|
||||
Threshold float64 `json:"threshold,omitempty"`
|
||||
PrefixPaddingMs int `json:"prefix_padding_ms,omitempty"`
|
||||
SilenceDurationMs int `json:"silence_duration_ms,omitempty"`
|
||||
// The type of turn detection ("server_vad" or "none").
|
||||
Type TurnDetectionType `json:"type"`
|
||||
// Activation threshold for VAD.
|
||||
Threshold float64 `json:"threshold,omitempty"`
|
||||
// Audio included before speech starts (in milliseconds).
|
||||
PrefixPaddingMs int `json:"prefix_padding_ms,omitempty"`
|
||||
// Duration of silence to detect speech stop (in milliseconds).
|
||||
SilenceDurationMs int `json:"silence_duration_ms,omitempty"`
|
||||
}
|
||||
|
||||
type ToolType string
|
||||
@@ -83,8 +87,10 @@ const (
|
||||
)
|
||||
|
||||
type InputAudioTranscription struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Model string `json:"model"`
|
||||
// Whether input audio transcription is enabled.
|
||||
Enabled bool `json:"enabled"`
|
||||
// The model used for transcription.
|
||||
Model string `json:"model"`
|
||||
}
|
||||
|
||||
type Tool struct {
|
||||
@@ -113,30 +119,45 @@ const (
|
||||
)
|
||||
|
||||
type MessageContentPart struct {
|
||||
Type MessageContentType `json:"type"`
|
||||
Text string `json:"text,omitempty"`
|
||||
Audio string `json:"audio,omitempty"`
|
||||
Transcript string `json:"transcript,omitempty"`
|
||||
// The content type.
|
||||
Type MessageContentType `json:"type"`
|
||||
// The text content. Validated if type is text.
|
||||
Text string `json:"text,omitempty"`
|
||||
// Base64-encoded audio data. Validated if type is audio.
|
||||
Audio string `json:"audio,omitempty"`
|
||||
// The transcript of the audio. Validated if type is transcript.
|
||||
Transcript string `json:"transcript,omitempty"`
|
||||
}
|
||||
|
||||
type MessageItem struct {
|
||||
ID string `json:"id"`
|
||||
Type MessageItemType `json:"type"`
|
||||
Status ItemStatus `json:"status"`
|
||||
Role MessageRole `json:"role"`
|
||||
// The unique ID of the item.
|
||||
ID string `json:"id"`
|
||||
// The type of the item ("message", "function_call", "function_call_output").
|
||||
Type MessageItemType `json:"type"`
|
||||
// The final status of the item.
|
||||
Status ItemStatus `json:"status"`
|
||||
// The role associated with the item.
|
||||
Role MessageRole `json:"role"`
|
||||
// The content of the item.
|
||||
Content []MessageContentPart `json:"content"`
|
||||
}
|
||||
|
||||
type ResponseMessageItem struct {
|
||||
MessageItem
|
||||
// The object type, must be "realtime.item".
|
||||
Object string `json:"object,omitempty"`
|
||||
}
|
||||
|
||||
type Error struct {
|
||||
// The type of error (e.g., "invalid_request_error", "server_error").
|
||||
Message string `json:"message,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Code string `json:"code,omitempty"`
|
||||
Param string `json:"param,omitempty"`
|
||||
// Error code, if any.
|
||||
Type string `json:"type,omitempty"`
|
||||
// A human-readable error message.
|
||||
Code string `json:"code,omitempty"`
|
||||
// Parameter related to the error, if any.
|
||||
Param string `json:"param,omitempty"`
|
||||
// The event_id of the client event that caused the error, if applicable.
|
||||
EventID string `json:"event_id,omitempty"`
|
||||
}
|
||||
|
||||
@@ -177,20 +198,34 @@ func (m ServerToolChoice) Get() ToolChoiceInterface {
|
||||
}
|
||||
|
||||
type ServerSession struct {
|
||||
ID string `json:"id"`
|
||||
Object string `json:"object"`
|
||||
Model string `json:"model"`
|
||||
Modalities []Modality `json:"modalities,omitempty"`
|
||||
Instructions string `json:"instructions,omitempty"`
|
||||
Voice Voice `json:"voice,omitempty"`
|
||||
InputAudioFormat AudioFormat `json:"input_audio_format,omitempty"`
|
||||
OutputAudioFormat AudioFormat `json:"output_audio_format,omitempty"`
|
||||
// The unique ID of the session.
|
||||
ID string `json:"id"`
|
||||
// The object type, must be "realtime.session".
|
||||
Object string `json:"object"`
|
||||
// The default model used for this session.
|
||||
Model string `json:"model"`
|
||||
// The set of modalities the model can respond with.
|
||||
Modalities []Modality `json:"modalities,omitempty"`
|
||||
// The default system instructions.
|
||||
Instructions string `json:"instructions,omitempty"`
|
||||
// The voice the model uses to respond - one of alloy, echo, or shimmer.
|
||||
Voice Voice `json:"voice,omitempty"`
|
||||
// The format of input audio.
|
||||
InputAudioFormat AudioFormat `json:"input_audio_format,omitempty"`
|
||||
// The format of output audio.
|
||||
OutputAudioFormat AudioFormat `json:"output_audio_format,omitempty"`
|
||||
// Configuration for input audio transcription.
|
||||
InputAudioTranscription *InputAudioTranscription `json:"input_audio_transcription,omitempty"`
|
||||
TurnDetection *TurnDetection `json:"turn_detection,omitempty"`
|
||||
Tools []Tool `json:"tools,omitempty"`
|
||||
ToolChoice ServerToolChoice `json:"tool_choice,omitempty"`
|
||||
Temperature *float32 `json:"temperature,omitempty"`
|
||||
MaxOutputTokens int `json:"max_output_tokens,omitempty"`
|
||||
// Configuration for turn detection.
|
||||
TurnDetection *TurnDetection `json:"turn_detection,omitempty"`
|
||||
// Tools (functions) available to the model.
|
||||
Tools []Tool `json:"tools,omitempty"`
|
||||
// How the model chooses tools.
|
||||
ToolChoice ServerToolChoice `json:"tool_choice,omitempty"`
|
||||
// Sampling temperature.
|
||||
Temperature *float32 `json:"temperature,omitempty"`
|
||||
// Maximum number of output tokens.
|
||||
MaxOutputTokens IntOrInf `json:"max_output_tokens,omitempty"`
|
||||
}
|
||||
|
||||
type ItemStatus string
|
||||
@@ -202,7 +237,9 @@ const (
|
||||
)
|
||||
|
||||
type Conversation struct {
|
||||
ID string `json:"id"`
|
||||
// The unique ID of the conversation.
|
||||
ID string `json:"id"`
|
||||
// The object type, must be "realtime.conversation".
|
||||
Object string `json:"object"`
|
||||
}
|
||||
|
||||
@@ -223,17 +260,27 @@ type Usage struct {
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
ID string `json:"id"`
|
||||
Object string `json:"object"`
|
||||
Status ResponseStatus `json:"status"`
|
||||
StatusDetails any `json:"status_details,omitempty"`
|
||||
Output []ResponseMessageItem `json:"output"`
|
||||
Usage *Usage `json:"usage,omitempty"`
|
||||
// The unique ID of the response.
|
||||
ID string `json:"id"`
|
||||
// The object type, must be "realtime.response".
|
||||
Object string `json:"object"`
|
||||
// The status of the response.
|
||||
Status ResponseStatus `json:"status"`
|
||||
// Additional details about the status.
|
||||
StatusDetails any `json:"status_details,omitempty"`
|
||||
// The list of output items generated by the response.
|
||||
Output []ResponseMessageItem `json:"output"`
|
||||
// Usage statistics for the response.
|
||||
Usage *Usage `json:"usage,omitempty"`
|
||||
}
|
||||
|
||||
type RateLimit struct {
|
||||
Name string `json:"name"`
|
||||
Limit int `json:"limit"`
|
||||
Remaining int `json:"remaining"`
|
||||
// The name of the rate limit ("requests", "tokens", "input_tokens", "output_tokens").
|
||||
Name string `json:"name"`
|
||||
// The maximum allowed value for the rate limit.
|
||||
Limit int `json:"limit"`
|
||||
// The remaining value before the limit is reached.
|
||||
Remaining int `json:"remaining"`
|
||||
// Seconds until the rate limit resets.
|
||||
ResetSeconds float64 `json:"reset_seconds"`
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// GenerateId generates a random ID with a prefix and a specified length.
|
||||
// The length of the returned ID is equal to the length parameter, therefore the prefix must be shorter than the length.
|
||||
func GenerateId(prefix string, length int) string {
|
||||
const chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
if length <= len(prefix) {
|
||||
|
||||
@@ -18,4 +18,8 @@ func TestGenerateId(t *testing.T) {
|
||||
t.Logf("generated: %s", generated)
|
||||
assert.True(t, strings.HasPrefix(generated, "test_"))
|
||||
assert.Equal(t, 20, len(generated))
|
||||
|
||||
generated = openairt.GenerateId("test_", 5)
|
||||
t.Logf("generated: %s", generated)
|
||||
assert.Equal(t, "test_", generated)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user