Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speech recognition tests #167

Merged
merged 8 commits into from
Nov 13, 2023
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
2 changes: 1 addition & 1 deletion progress/sergey-karasev.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
2023-11-10 Fri: Working on [truncating the accumulating context to a maximum of 512 characters](https://github.com/harmony-one/x/pull/159) and adding unit tests for the "limiter", [added the same logic to harmony one bot](https://github.com/harmony-one/HarmonyOneBot/pull/343)
2023-11-10 Fri: Working on [truncating the accumulating context to a maximum of 512 characters](https://github.com/harmony-one/x/pull/159) and adding unit tests for the "limiter"

2023-11-09 Thu: I have added [a window to display a link to the application](https://github.com/harmony-one/x/pull/142) (share feature) after the user taps "new session" button for the seventh time, also [added a throttler](https://github.com/harmony-one/x/pull/144) to the reset session function (in order not to interrupt the greeting). Clarified the code regarding tap-to-speak and [fixed the play-pause button state](https://github.com/harmony-one/x/pull/149)

Expand Down
8 changes: 1 addition & 7 deletions progress/theo-fandrich.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
2023-11-10 Fri: Made a 9am push that integrated some new support for in App purchases coming soon. Working on few small bugs still in place such has long press triggering tap functionality, overlap of "Tap to Speak" & "Press & Hold" functionality, and will improve logic for free credits.

2023-11-09 Thu: Made a huge push for 3 initial releases to the app store today. Download voice AI on the App Store [here](x.country/app).

2023-11-08 Wed: Worked on engineers to fix bugs regarding UI inconsistencies and conducted product testing for rate limiting.

2023-11-07 Tue: Product tested, listed out bugs, delegated fixes to engineers, submitted to App Store connect.
2023-11-07 Tue: Product tested, listed out bugs, delegated fixes to engineers, submitted to App store connect.

2023-11-06 Mon: Worked on preparing app store submission. Calculated pricing for Voice AI and documented how the backend and iOS app should communicate to support the bahavior. The updated UI will be implemented by Tuesday morning.

Expand Down
2 changes: 1 addition & 1 deletion progress/yuriy-menkov.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
2023-11-10 Fri: [Resolved](https://github.com/harmony-one/x/pull/161) issue with long press actions (Ensure long press actions do not trigger tap actions vice versa). Working on tracking active using app time and showing suggestions to share with friends and share on Twitter.
2023-11-10 Fri: Resolved issue with long press actions (Ensure long press actions do not trigger tap actions vice versa). Working on tracking active using app time and showing suggestions to share with friends and share on Twitter.

2023-11-9 Thu: [Added](https://github.com/harmony-one/x/pull/148/files) the ability to repeat the current session to resolve repeat bug (When hitting "Repeat" during the first stream, it says "Hey" while the stream is going. It should just start again from the beginning instead.)

Expand Down
17 changes: 11 additions & 6 deletions voice/voice-ai/Voice AI.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@
B36367562AFC69F2000409FC /* RandomFactTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B31CDCE62AFC644D00AB39EE /* RandomFactTests.swift */; };
B36367572AFC6A04000409FC /* MockGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F1150D2AF825F700BC191C /* MockGenerator.swift */; };
B38ADB9D2AFE0A0F006BDC93 /* AppConfig.plist in Resources */ = {isa = PBXBuildFile; fileRef = F72708412AFD672E000DE81D /* AppConfig.plist */; };
B3C083B32AF1BADB0069232C /* OpenAITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3C083B22AF1BADB0069232C /* OpenAITests.swift */; };
B3C0FE4B2AFEC68800B712E7 /* IAPTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3C0FE4A2AFEC68800B712E7 /* IAPTests.swift */; };
B3C083B32AF1BADB0069232C /* MessageContextTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3C083B22AF1BADB0069232C /* MessageContextTests.swift */; };
B3D0A3442AF29B1B00E8B0DA /* MockNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3D0A3432AF29B1B00E8B0DA /* MockNetworkService.swift */; };
B91681282AFBA3A80006E463 /* ReviewRequester.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9B331A02AFB803500F6A9C9 /* ReviewRequester.swift */; };
B919B7BF2AF3C3F7006335D1 /* AudioEngineAndSessionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B919B7BE2AF3C3F7006335D1 /* AudioEngineAndSessionTests.swift */; };
Expand Down Expand Up @@ -157,6 +156,8 @@
F61049122AF02DF50087F745 /* SwiftyJSON in Frameworks */ = {isa = PBXBuildFile; productRef = F61049112AF02DF50087F745 /* SwiftyJSON */; };
F67E43322AFAC166001B72CD /* SentrySwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = F67E43312AFAC166001B72CD /* SentrySwiftUI */; };
F67E43342AFAC16C001B72CD /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = F67E43332AFAC16C001B72CD /* Sentry */; };
F723CC1F2AFECE2000B2A23A /* TextToSpeechConverterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F723CC1E2AFECE2000B2A23A /* TextToSpeechConverterTests.swift */; };
F723CC212AFEFFA400B2A23A /* MockAVSpeechSynthesizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F723CC202AFEFFA400B2A23A /* MockAVSpeechSynthesizer.swift */; };
F72708422AFD672E000DE81D /* AppConfig.plist in Resources */ = {isa = PBXBuildFile; fileRef = F72708412AFD672E000DE81D /* AppConfig.plist */; };
F7C16FE82AFC576000D11529 /* ThemeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B346DF772AF562020023FC87 /* ThemeManager.swift */; };
F7F115052AF8173300BC191C /* SpeechRecognitionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7F114F52AF8172800BC191C /* SpeechRecognitionTests.swift */; };
Expand Down Expand Up @@ -233,8 +234,7 @@
B346DF772AF562020023FC87 /* ThemeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeManager.swift; sourceTree = "<group>"; };
B3B3BA792AFB40A300D8F8C6 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = "<group>"; };
B3C083B12AF1948D0069232C /* OpenAIService.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = OpenAIService.xctestplan; path = x/OpenAIService.xctestplan; sourceTree = SOURCE_ROOT; };
B3C083B22AF1BADB0069232C /* OpenAITests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpenAITests.swift; sourceTree = "<group>"; };
B3C0FE4A2AFEC68800B712E7 /* IAPTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IAPTests.swift; sourceTree = "<group>"; };
B3C083B22AF1BADB0069232C /* MessageContextTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageContextTests.swift; sourceTree = "<group>"; };
B3D0A3432AF29B1B00E8B0DA /* MockNetworkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockNetworkService.swift; sourceTree = "<group>"; };
B919B7BE2AF3C3F7006335D1 /* AudioEngineAndSessionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioEngineAndSessionTests.swift; sourceTree = "<group>"; };
B930AADC2ADE2DE5009F9F8C /* Color.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -279,6 +279,8 @@
CD0D13682ADA74D100031EDD /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS17.0.sdk/System/Library/Frameworks/AVFoundation.framework; sourceTree = DEVELOPER_DIR; };
CD0D136A2ADB28CE00031EDD /* logo.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = logo.png; sourceTree = SOURCE_ROOT; };
F61049092AF02D820087F745 /* OpenAIStreamService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpenAIStreamService.swift; sourceTree = "<group>"; };
F723CC1E2AFECE2000B2A23A /* TextToSpeechConverterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextToSpeechConverterTests.swift; sourceTree = "<group>"; };
F723CC202AFEFFA400B2A23A /* MockAVSpeechSynthesizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockAVSpeechSynthesizer.swift; sourceTree = "<group>"; };
F72708412AFD672E000DE81D /* AppConfig.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = AppConfig.plist; sourceTree = "<group>"; };
F7F114F52AF8172800BC191C /* SpeechRecognitionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpeechRecognitionTests.swift; sourceTree = "<group>"; };
F7F114F62AF8172800BC191C /* PermissionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PermissionTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -603,7 +605,8 @@
F7F1150D2AF825F700BC191C /* MockGenerator.swift */,
B31CDCE62AFC644D00AB39EE /* RandomFactTests.swift */,
6E35CB4A2AFE86130004D2D2 /* OpenAIUtilsTests.swift */,
B3C0FE4A2AFEC68800B712E7 /* IAPTests.swift */,
F723CC1E2AFECE2000B2A23A /* TextToSpeechConverterTests.swift */,
F723CC202AFEFFA400B2A23A /* MockAVSpeechSynthesizer.swift */,
);
path = xTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -987,6 +990,7 @@
F7F1150C2AF8173300BC191C /* DashboardViewTests.swift in Sources */,
F7F115062AF8173300BC191C /* StringTests.swift in Sources */,
B31CDCE42AFC565400AB39EE /* ThemeManager.swift in Sources */,
F723CC212AFEFFA400B2A23A /* MockAVSpeechSynthesizer.swift in Sources */,
B9C4A81F2AEE594900327529 /* MockSpeechRecognition.swift in Sources */,
F610490B2AF02D820087F745 /* OpenAIStreamService.swift in Sources */,
B36367562AFC69F2000409FC /* RandomFactTests.swift in Sources */,
Expand All @@ -997,6 +1001,7 @@
B9C4A8322AEE96B600327529 /* Usage.swift in Sources */,
F7F1150A2AF8173300BC191C /* VibrationManagerTests.swift in Sources */,
B36367572AFC6A04000409FC /* MockGenerator.swift in Sources */,
F723CC1F2AFECE2000B2A23A /* TextToSpeechConverterTests.swift in Sources */,
A40CFCE42AF98BB700E02128 /* RandomFact.swift in Sources */,
B9C4A8312AEE96B300327529 /* OpenAIResponse.swift in Sources */,
F7F115082AF8173300BC191C /* AudioPlayerTests.swift in Sources */,
Expand All @@ -1011,7 +1016,7 @@
F7F115072AF8173300BC191C /* PermissionTests.swift in Sources */,
6E53AF4C2AF012760022A8F2 /* GridButton.swift in Sources */,
B9C4A82F2AEE96AE00327529 /* Choices.swift in Sources */,
B3C083B32AF1BADB0069232C /* OpenAITests.swift in Sources */,
B3C083B32AF1BADB0069232C /* MessageContextTests.swift in Sources */,
B9C4A82C2AEE967200327529 /* AudioPlayer.swift in Sources */,
6E53AF512AF012A40022A8F2 /* Color.swift in Sources */,
);
Expand Down
64 changes: 3 additions & 61 deletions voice/voice-ai/x/Actions/GridButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,74 +7,17 @@ struct GridButton: View {
var foregroundColor: Color
var active: Bool = false
var isPressed: Bool = false

@State private var timeAtPress = Date()
@State private var isDragActive = false

var image: String? = nil
var colorExternalManage: Bool = false
var action: () -> Void
let buttonSize: CGFloat = 100
let imageTextSpacing: CGFloat = 40
@Environment(\.verticalSizeClass) var verticalSizeClass
@Environment(\.horizontalSizeClass) var horizontalSizeClass

func onDragEnded() {
self.isDragActive = false
}

func onDragStart() {
if(!self.isDragActive) {
self.isDragActive = true

self.timeAtPress = Date()
}
}

var body: some View {
let drag = DragGesture(minimumDistance: 0)
.onChanged({ drag in
self.onDragStart()
})
.onEnded({ drag in
self.onDragEnded()
})

let hackyPinch = MagnificationGesture(minimumScaleDelta: 0.0)
.onChanged({ delta in
self.onDragEnded()
})
.onEnded({ delta in
self.onDragEnded()
})

let hackyRotation = RotationGesture(minimumAngleDelta: Angle(degrees: 0.0))
.onChanged({ delta in
self.onDragEnded()
})
.onEnded({ delta in
self.onDragEnded()
})

let hackyPress = LongPressGesture(minimumDuration: 0.0, maximumDistance: 0.0)
.onChanged({ _ in
self.onDragEnded()
})
.onEnded({ delta in
self.onDragEnded()
})

let combinedGesture = drag
.simultaneously(with: hackyPinch)
.simultaneously(with: hackyRotation)
.exclusively(before: hackyPress)

return Button(action: {
let elapsed = Date().timeIntervalSince(self.timeAtPress)

if(elapsed < 3) {
action()
}
var body: some View {
Button(action: {
action()
}) {
VStack(spacing: imageTextSpacing) {
Image(pressEffectButtonImage()) // button.image)
Expand All @@ -91,7 +34,6 @@ struct GridButton: View {
.alignmentGuide(.bottom) { _ in 0.5 }
}
.buttonStyle(PressEffectButtonStyle(theme: currentTheme, active: active, invertColors: button.action == .speak && button.pressedLabel == nil))
.simultaneousGesture(combinedGesture)
}

private func pressEffectButtonImage() -> String {
Expand Down
2 changes: 1 addition & 1 deletion voice/voice-ai/x/SpeechRecognition/SpeechRecognition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class SpeechRecognition: NSObject, ObservableObject, SpeechRecognitionProtocol {
}

@Published private var _isPlaying = false
var isPlaingPublisher: Published<Bool>.Publisher {
var isPlayingPublisher: Published<Bool>.Publisher {
$_isPlaying
}

Expand Down
21 changes: 0 additions & 21 deletions voice/voice-ai/xTests/IAPTests.swift

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -24,59 +24,6 @@ class OpenAIServiceTests: XCTestCase {
}
}

class OpenAIResponseTests: XCTestCase {

func testInit() throws {
// Given
let json = """
{
"id": "123",
"object": "response",
"created": 1635790771,
"model": "gpt-3.5-turbo",
"choices": [
{
"message": {
"role": "user",
"content": "Hi"
},
"finish_reason": "OK",
"index": 1

},
],
"usage": {
"prompt_tokens": 10,
"completion_tokens": 50,
"total_tokens": 60
}
}
"""

// When
let jsonData = Data(json.utf8)
let response = try JSONDecoder().decode(OpenAIResponse.self, from: jsonData)

// Then
XCTAssertEqual(response.id, "123")
XCTAssertEqual(response.object, "response")
XCTAssertEqual(response.created, 1635790771)
XCTAssertEqual(response.model, "gpt-3.5-turbo")

XCTAssertEqual(response.choices?.count, 1)
XCTAssertEqual(response.choices?[0].message?.role, "user")
XCTAssertEqual(response.choices?[0].message?.content, "Hi")

XCTAssertNotNil(response.usage)
XCTAssertEqual(response.usage?.prompt_tokens, 10)
XCTAssertEqual(response.usage?.completion_tokens, 50)
XCTAssertEqual(response.usage?.total_tokens, 60)
}

// Add more test cases as needed

}

class MessageTests: XCTestCase {
func testInitialization() {
// Test initializing a Message instance
Expand Down
13 changes: 12 additions & 1 deletion voice/voice-ai/xTests/MockSpeechRecognition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,31 @@ class MockSpeechRecognition: SpeechRecognitionProtocol {
var repeateCalled: Bool = false

private var _isPlaying = false
private var _isPausing = false

private var isPlayingSubject = PassthroughSubject<Bool, Never>()
private var isPausingSubject = PassthroughSubject<Bool, Never>()

// Define a custom publisher and use isPlayingSubject to emit values
var isPlaingPublisher: AnyPublisher<Bool, Never> {
var isPlayingPublisher: AnyPublisher<Bool, Never> {
return isPlayingSubject.eraseToAnyPublisher()
}

var isPausingPublisher: AnyPublisher<Bool, Never> {
return isPausingSubject.eraseToAnyPublisher()
}

// Implement a method to update the value and notify subscribers
func setIsPlaying(_ isPlaying: Bool) {
_isPlaying = isPlaying
isPlayingSubject.send(isPlaying)
}

func setIsPausing(_ isPausing: Bool) {
_isPausing = isPausing
isPausingSubject.send(isPausing)
}

func pause(feedback: Bool?) {}

func surprise() {
Expand Down
Loading
Loading