Skip to content

Commit fd90082

Browse files
authored
feat: adds support for IUM (#304)
* feat: adds support for IUM * chore: attempt to fix unit test * chore: resolve code rabbit review * chore: fixes unit test location
1 parent 9f5494a commit fd90082

File tree

5 files changed

+222
-1
lines changed

5 files changed

+222
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1181,7 +1181,7 @@ To run the tests, you can use the following commands:
11811181
Run specific tests in a directory:
11821182

11831183
```bash
1184-
go run filename
1184+
go test filename
11851185
```
11861186

11871187
## Backwards Compatibility

pkg/api/agent/v1/websocket/interfaces/constants.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const (
1717
TypeUpdatePrompt = "UpdatePrompt"
1818
TypeUpdateSpeak = "UpdateSpeak"
1919
TypeInjectAgentMessage = "InjectAgentMessage"
20+
TypeInjectUserMessage = "InjectUserMessage"
2021
TypeFunctionCallResponse = "FunctionCallResponse"
2122
TypeKeepAlive = "KeepAlive"
2223
TypeClose = "Close"

pkg/api/agent/v1/websocket/interfaces/types.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ type InjectAgentMessage struct {
3232
Content string `json:"content,omitempty"`
3333
}
3434

35+
// InjectUserMessage is the request to interact with the agent using text.
36+
type InjectUserMessage struct {
37+
Type string `json:"type,omitempty"`
38+
Content string `json:"content,omitempty"`
39+
}
40+
3541
// FunctionCallResponse is the response from a function call
3642
type FunctionCallResponse struct {
3743
Type string `json:"type,omitempty"`

pkg/client/agent/v1/websocket/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type SettingsOptions interfaces.SettingsOptions
1818
type UpdatePrompt msginterface.UpdatePrompt
1919
type UpdateSpeak msginterface.UpdateSpeak
2020
type InjectAgentMessage msginterface.InjectAgentMessage
21+
type InjectUserMessage msginterface.InjectUserMessage
2122
type FunctionCallResponse msginterface.FunctionCallResponse
2223
type KeepAlive msginterface.KeepAlive
2324

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
// Copyright 2024 Deepgram SDK contributors. All Rights Reserved.
2+
// Use of this source code is governed by a MIT license that can be found in the LICENSE file.
3+
// SPDX-License-Identifier: MIT
4+
5+
package deepgram_test
6+
7+
import (
8+
"encoding/json"
9+
"testing"
10+
11+
msginterfaces "github.com/deepgram/deepgram-go-sdk/v3/pkg/api/agent/v1/websocket/interfaces"
12+
websocketv1 "github.com/deepgram/deepgram-go-sdk/v3/pkg/client/agent/v1/websocket"
13+
)
14+
15+
func TestInjectUserMessage_StructCreation(t *testing.T) {
16+
t.Run("Test InjectUserMessage struct creation", func(t *testing.T) {
17+
testContent := "Hello, how can you help me today?"
18+
19+
// Test creating the message struct
20+
msg := msginterfaces.InjectUserMessage{
21+
Type: msginterfaces.TypeInjectUserMessage,
22+
Content: testContent,
23+
}
24+
25+
// Verify the struct fields are set correctly
26+
if msg.Type != msginterfaces.TypeInjectUserMessage {
27+
t.Errorf("Expected Type to be %s, got %s", msginterfaces.TypeInjectUserMessage, msg.Type)
28+
}
29+
30+
if msg.Content != testContent {
31+
t.Errorf("Expected Content to be %s, got %s", testContent, msg.Content)
32+
}
33+
})
34+
}
35+
36+
func TestInjectUserMessage_JSONMarshaling(t *testing.T) {
37+
t.Run("Test InjectUserMessage JSON marshaling", func(t *testing.T) {
38+
testContent := "What services do you offer?"
39+
40+
// Create the message
41+
msg := msginterfaces.InjectUserMessage{
42+
Type: msginterfaces.TypeInjectUserMessage,
43+
Content: testContent,
44+
}
45+
46+
// Marshal to JSON
47+
jsonData, err := json.Marshal(msg)
48+
if err != nil {
49+
t.Errorf("Failed to marshal InjectUserMessage to JSON: %v", err)
50+
}
51+
52+
// Verify JSON structure
53+
var result map[string]interface{}
54+
err = json.Unmarshal(jsonData, &result)
55+
if err != nil {
56+
t.Errorf("Failed to unmarshal JSON: %v", err)
57+
}
58+
59+
// Check the JSON contains the expected fields
60+
if result["type"] != msginterfaces.TypeInjectUserMessage {
61+
t.Errorf("Expected JSON type field to be %s, got %v", msginterfaces.TypeInjectUserMessage, result["type"])
62+
}
63+
64+
if result["content"] != testContent {
65+
t.Errorf("Expected JSON content field to be %s, got %v", testContent, result["content"])
66+
}
67+
})
68+
}
69+
70+
func TestInjectUserMessage_JSONUnmarshaling(t *testing.T) {
71+
t.Run("Test InjectUserMessage JSON unmarshaling", func(t *testing.T) {
72+
// Create test JSON string using the constant
73+
testJSON := `{
74+
"type": "` + msginterfaces.TypeInjectUserMessage + `",
75+
"content": "Can you explain how this works?"
76+
}`
77+
78+
// Unmarshal from JSON
79+
var msg msginterfaces.InjectUserMessage
80+
err := json.Unmarshal([]byte(testJSON), &msg)
81+
if err != nil {
82+
t.Errorf("Failed to unmarshal JSON to InjectUserMessage: %v", err)
83+
}
84+
85+
// Verify the struct was populated correctly
86+
if msg.Type != msginterfaces.TypeInjectUserMessage {
87+
t.Errorf("Expected Type to be %s, got %s", msginterfaces.TypeInjectUserMessage, msg.Type)
88+
}
89+
90+
if msg.Content != "Can you explain how this works?" {
91+
t.Errorf("Expected Content to be 'Can you explain how this works?', got %s", msg.Content)
92+
}
93+
})
94+
}
95+
96+
func TestInjectUserMessage_TypeAlias(t *testing.T) {
97+
t.Run("Test InjectUserMessage type alias works correctly", func(t *testing.T) {
98+
testContent := "I need assistance with my account"
99+
100+
// Test using the client type alias
101+
clientMsg := websocketv1.InjectUserMessage{
102+
Type: msginterfaces.TypeInjectUserMessage,
103+
Content: testContent,
104+
}
105+
106+
// Verify the alias works the same as the interface type
107+
if clientMsg.Type != msginterfaces.TypeInjectUserMessage {
108+
t.Errorf("Expected Type to be %s, got %s", msginterfaces.TypeInjectUserMessage, clientMsg.Type)
109+
}
110+
111+
if clientMsg.Content != testContent {
112+
t.Errorf("Expected Content to be %s, got %s", testContent, clientMsg.Content)
113+
}
114+
115+
// Test JSON marshaling with the alias
116+
jsonData, err := json.Marshal(clientMsg)
117+
if err != nil {
118+
t.Errorf("Failed to marshal client type alias to JSON: %v", err)
119+
}
120+
121+
// Verify it produces the same JSON structure
122+
var result map[string]interface{}
123+
err = json.Unmarshal(jsonData, &result)
124+
if err != nil {
125+
t.Errorf("Failed to unmarshal JSON: %v", err)
126+
}
127+
128+
if result["type"] != msginterfaces.TypeInjectUserMessage {
129+
t.Errorf("Expected JSON type field to be %s, got %v", msginterfaces.TypeInjectUserMessage, result["type"])
130+
}
131+
})
132+
}
133+
134+
func TestInjectUserMessage_Constants(t *testing.T) {
135+
t.Run("Test InjectUserMessage constants are properly defined", func(t *testing.T) {
136+
// Verify the constant is defined and has the expected value
137+
expectedType := "InjectUserMessage"
138+
if msginterfaces.TypeInjectUserMessage != expectedType {
139+
t.Errorf("Expected TypeInjectUserMessage constant to be %s, got %s", expectedType, msginterfaces.TypeInjectUserMessage)
140+
}
141+
})
142+
}
143+
144+
func TestInjectUserMessage_EmptyContent(t *testing.T) {
145+
t.Run("Test InjectUserMessage with empty content", func(t *testing.T) {
146+
// Test creating message with empty content
147+
msg := msginterfaces.InjectUserMessage{
148+
Type: msginterfaces.TypeInjectUserMessage,
149+
Content: "",
150+
}
151+
152+
// Should still marshal to valid JSON
153+
jsonData, err := json.Marshal(msg)
154+
if err != nil {
155+
t.Errorf("Failed to marshal InjectUserMessage with empty content: %v", err)
156+
}
157+
158+
// Verify JSON structure
159+
var result map[string]interface{}
160+
err = json.Unmarshal(jsonData, &result)
161+
if err != nil {
162+
t.Errorf("Failed to unmarshal JSON: %v", err)
163+
}
164+
165+
// With omitempty tag, empty content field should be omitted from JSON entirely
166+
if _, exists := result["content"]; exists {
167+
t.Errorf("Expected content key to be omitted from JSON when empty, but it was present")
168+
}
169+
170+
// Verify we can unmarshal back to the struct correctly
171+
var reconstructed msginterfaces.InjectUserMessage
172+
err = json.Unmarshal(jsonData, &reconstructed)
173+
if err != nil {
174+
t.Errorf("Failed to unmarshal back to struct: %v", err)
175+
}
176+
177+
if reconstructed.Type != msginterfaces.TypeInjectUserMessage {
178+
t.Errorf("Expected Type to be %s, got %s", msginterfaces.TypeInjectUserMessage, reconstructed.Type)
179+
}
180+
181+
if reconstructed.Content != "" {
182+
t.Errorf("Expected Content to be empty string, got %s", reconstructed.Content)
183+
}
184+
})
185+
}
186+
187+
func TestInjectUserMessage_SpecialCharacters(t *testing.T) {
188+
t.Run("Test InjectUserMessage with special characters", func(t *testing.T) {
189+
// Test with various special characters and unicode
190+
testContent := "Hello! How do you handle émojis 🚀 and special chars like @#$%?"
191+
192+
msg := msginterfaces.InjectUserMessage{
193+
Type: msginterfaces.TypeInjectUserMessage,
194+
Content: testContent,
195+
}
196+
197+
// Marshal and unmarshal to ensure proper handling
198+
jsonData, err := json.Marshal(msg)
199+
if err != nil {
200+
t.Errorf("Failed to marshal InjectUserMessage with special characters: %v", err)
201+
}
202+
203+
var result msginterfaces.InjectUserMessage
204+
err = json.Unmarshal(jsonData, &result)
205+
if err != nil {
206+
t.Errorf("Failed to unmarshal JSON with special characters: %v", err)
207+
}
208+
209+
if result.Content != testContent {
210+
t.Errorf("Special characters not preserved. Expected %s, got %s", testContent, result.Content)
211+
}
212+
})
213+
}

0 commit comments

Comments
 (0)