Skip to content
Open
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
54 changes: 25 additions & 29 deletions TypeaheadAI/Actors/SpecialCopyActor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,41 +33,37 @@ actor SpecialCopyActor: CanSimulateCopy {
}

self.logger.debug("copied '\(copiedText)'")

// Clear the modal text and reissue request
self.modalManager.clearText(stickyMode: stickyMode)
self.modalManager.showModal(incognito: incognitoMode)
var truncated: String = copiedText
if (copiedText.count > 280) {
truncated = "\(truncated.prefix(280))..."
}

if let activePrompt = self.clientManager.getActivePrompt() {
self.modalManager.setUserMessage("\(activePrompt)\n:\(truncated)")
} else {
self.modalManager.setUserMessage("copied:\n\(truncated)")
}
Task {
await self.modalManager.clearText(stickyMode: stickyMode)
if let activePrompt = self.clientManager.getActivePrompt() {
await self.modalManager.setUserMessage("\(activePrompt):\n\(copiedText)")
} else {
await self.modalManager.setUserMessage("copied:\n\(copiedText)")
}

self.clientManager.predict(
id: UUID(),
copiedText: copiedText,
incognitoMode: incognitoMode,
stream: true,
streamHandler: { result in
switch result {
case .success(let chunk):
Task {
await self.modalManager.appendText(chunk)
self.clientManager.refine(
messages: self.modalManager.messages,
incognitoMode: incognitoMode,
streamHandler: { result in
switch result {
case .success(let chunk):
Task {
await self.modalManager.appendText(chunk)
}
self.logger.info("Received chunk: \(chunk)")
case .failure(let error):
DispatchQueue.main.async {
self.modalManager.setError(error.localizedDescription)
}
self.logger.error("An error occurred: \(error)")
}
self.logger.info("Received chunk: \(chunk)")
case .failure(let error):
DispatchQueue.main.async {
self.modalManager.setError(error.localizedDescription)
}
self.logger.error("An error occurred: \(error)")
}
},
completion: { _ in }
)
)
}
}
}
}
12 changes: 7 additions & 5 deletions TypeaheadAI/Actors/SpecialCutActor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,15 @@ actor SpecialCutActor {
truncated = "\(truncated.prefix(280))..."
}

self.modalManager.clearText(stickyMode: stickyMode)
self.modalManager.showModal(incognito: incognitoMode)

if let activePrompt = self.clientManager.getActivePrompt() {
self.modalManager.setUserMessage("\(activePrompt)\n:\(truncated)")
} else {
self.modalManager.setUserMessage("cut:\n\(truncated)")
Task {
await self.modalManager.clearText(stickyMode: stickyMode)
if let activePrompt = self.clientManager.getActivePrompt() {
await self.modalManager.setUserMessage("\(activePrompt)\n:\(truncated)")
} else {
await self.modalManager.setUserMessage("cut:\n\(truncated)")
}
}

self.clientManager.predict(
Expand Down
5 changes: 4 additions & 1 deletion TypeaheadAI/Actors/SpecialSaveActor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ actor SpecialSaveActor: CanSimulateCopy {

self.logger.debug("saved '\(copiedText)'")
// Force sticky-mode so that it saves the message to the session.
self.modalManager.clearText(stickyMode: true)
Task {
await self.modalManager.clearText(stickyMode: true)
}

self.modalManager.showModal(incognito: incognitoMode)

Task {
Expand Down
26 changes: 21 additions & 5 deletions TypeaheadAI/AppContextManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class AppContextManager {
category: "AppContextManager"
)

func getActiveAppInfo(completion: @escaping (String?, String?, String?) -> Void) {
func getContext(completion: @escaping (AppContext) -> Void) {
self.logger.debug("get active app")
if let activeApp = NSWorkspace.shared.frontmostApplication {
let appName = activeApp.localizedName
Expand All @@ -28,17 +28,33 @@ class AppContextManager {
self.scriptManager.executeScript { (result, error) in
if let error = error {
self.logger.error("Failed to execute script: \(error.errorDescription ?? "Unknown error")")
completion(appName, bundleIdentifier, nil)
completion(AppContext(
activeAppName: appName,
activeAppBundleIdentifier: bundleIdentifier,
url: nil
))
} else if let url = result?.stringValue {
self.logger.info("Successfully executed script. URL: \(url)")
completion(appName, bundleIdentifier, url)
completion(AppContext(
activeAppName: appName,
activeAppBundleIdentifier: bundleIdentifier,
url: url
))
}
}
} else {
completion(appName, bundleIdentifier, nil)
completion(AppContext(
activeAppName: appName,
activeAppBundleIdentifier: bundleIdentifier,
url: nil
))
}
} else {
completion(nil, nil, nil)
completion(AppContext(
activeAppName: nil,
activeAppBundleIdentifier: nil,
url: nil
))
}
}
}
77 changes: 25 additions & 52 deletions TypeaheadAI/ClientManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@ struct RequestPayload: Codable {
var userObjective: String
var userBio: String
var userLang: String
var copiedText: String
// var copiedText: String? = nil
var messages: [Message]?
var url: String
var activeAppName: String
var activeAppBundleIdentifier: String
var appContext: AppContext?
var onboarding: Bool = false
}

Expand Down Expand Up @@ -50,8 +48,8 @@ class ClientManager {
private let session: URLSession

private let apiUrl = URL(string: "https://typeahead-ai.fly.dev/get_response")!
private let apiUrlStreaming = URL(string: "https://typeahead-ai.fly.dev/get_response_stream")!
// private let apiUrlStreaming = URL(string: "http://localhost:8080/get_response_stream")!
// private let apiUrlStreaming = URL(string: "https://typeahead-ai.fly.dev/get_response_stream")!
private let apiUrlStreaming = URL(string: "http://localhost:8080/get_response_stream")!

private let logger = Logger(
subsystem: "ai.typeahead.TypeaheadAI",
Expand Down Expand Up @@ -84,7 +82,7 @@ class ClientManager {
// If objective is not specified in the request, fall back on the active prompt.
let objective = userObjective ?? self.promptManager?.getActivePrompt() ?? (stream ? "respond to this in <20 words" : "respond to this")

appContextManager!.getActiveAppInfo { (appName, bundleIdentifier, url) in
appContextManager!.getContext { appContext in
if stream {
Task {
await self.sendStreamRequest(
Expand All @@ -96,9 +94,7 @@ class ClientManager {
userLang: Locale.preferredLanguages.first ?? "",
copiedText: copiedText,
messages: [],
url: url ?? "",
activeAppName: appName ?? "unknown",
activeAppBundleIdentifier: bundleIdentifier ?? "",
appContext: appContext,
incognitoMode: incognitoMode,
streamHandler: streamHandler,
completion: completion
Expand All @@ -114,9 +110,7 @@ class ClientManager {
userBio: UserDefaults.standard.string(forKey: "bio") ?? "",
userLang: Locale.preferredLanguages.first ?? "",
copiedText: copiedText,
url: url ?? "",
activeAppName: appName ?? "unknown",
activeAppBundleIdentifier: bundleIdentifier ?? "",
appContext: appContext,
incognitoMode: incognitoMode,
completion: completion
)
Expand All @@ -135,7 +129,7 @@ class ClientManager {
if let (key, _) = cached,
let data = key.data(using: .utf8),
let payload = try? JSONDecoder().decode(RequestPayload.self, from: data) {
appContextManager!.getActiveAppInfo { (appName, bundleIdentifier, url) in
appContextManager!.getContext { appContext in
Task {
await self.sendStreamRequest(
id: UUID(),
Expand All @@ -144,11 +138,9 @@ class ClientManager {
userObjective: payload.userObjective,
userBio: payload.userBio,
userLang: payload.userLang,
copiedText: payload.copiedText,
copiedText: nil, // payload.copiedText,
messages: self.sanitizeMessages(messages),
url: payload.url,
activeAppName: appName ?? "unknown",
activeAppBundleIdentifier: bundleIdentifier ?? "",
appContext: appContext,
incognitoMode: incognitoMode,
streamHandler: streamHandler,
completion: { _ in }
Expand All @@ -157,7 +149,7 @@ class ClientManager {
}
} else {
logger.error("No cached request to refine")
appContextManager!.getActiveAppInfo { (appName, bundleIdentifier, url) in
appContextManager!.getContext { appContext in
Task {
await self.sendStreamRequest(
id: UUID(),
Expand All @@ -168,9 +160,7 @@ class ClientManager {
userLang: Locale.preferredLanguages.first ?? "",
copiedText: "",
messages: self.sanitizeMessages(messages),
url: url ?? "unknown",
activeAppName: appName ?? "unknown",
activeAppBundleIdentifier: bundleIdentifier ?? "",
appContext: appContext,
incognitoMode: false,
streamHandler: streamHandler,
completion: { _ in }
Expand All @@ -187,7 +177,7 @@ class ClientManager {
streamHandler: @escaping (Result<String, Error>) -> Void
) {
if messages.isEmpty {
appContextManager!.getActiveAppInfo { (appName, bundleIdentifier, url) in
appContextManager!.getContext { appContext in
Task {
await self.sendStreamRequest(
id: UUID(),
Expand All @@ -198,9 +188,7 @@ class ClientManager {
userLang: Locale.preferredLanguages.first ?? "",
copiedText: "",
messages: self.sanitizeMessages(messages),
url: url ?? "unknown",
activeAppName: appName ?? "unknown",
activeAppBundleIdentifier: bundleIdentifier ?? "",
appContext: appContext,
incognitoMode: false,
onboardingMode: true,
streamHandler: streamHandler,
Expand All @@ -217,7 +205,7 @@ class ClientManager {
return
}

appContextManager!.getActiveAppInfo { (appName, bundleIdentifier, url) in
appContextManager!.getContext { appContext in
Task {
await self.sendStreamRequest(
id: UUID(),
Expand All @@ -226,11 +214,9 @@ class ClientManager {
userObjective: payload.userObjective,
userBio: payload.userBio,
userLang: payload.userLang,
copiedText: payload.copiedText,
copiedText: nil, // payload.copiedText,
messages: self.sanitizeMessages(messages),
url: payload.url,
activeAppName: appName ?? "unknown",
activeAppBundleIdentifier: bundleIdentifier ?? "",
appContext: appContext,
incognitoMode: false,
onboardingMode: true,
streamHandler: streamHandler,
Expand All @@ -251,9 +237,7 @@ class ClientManager {
/// - userBio: Details about the user.
/// - userLang: User's preferred language.
/// - copiedText: The text that the user has copied.
/// - url: The URL that the user is currently viewing.
/// - activeAppName: The name of the app that is currently active.
/// - activeAppBundleIdentifier: The bundle identifier of the currently active app.
/// - appContext: Currently active app context
/// - incognitoMode: Whether or not the request is sent to an online or offline model.
/// - timeout: The timeout for the request. Default is 10 seconds.
/// - completion: A closure to be executed once the request is complete.
Expand All @@ -265,9 +249,7 @@ class ClientManager {
userBio: String,
userLang: String,
copiedText: String,
url: String,
activeAppName: String,
activeAppBundleIdentifier: String,
appContext: AppContext,
incognitoMode: Bool,
timeout: TimeInterval = 10,
completion: @escaping (Result<String, Error>) -> Void
Expand All @@ -278,10 +260,7 @@ class ClientManager {
userObjective: userObjective,
userBio: userBio,
userLang: userLang,
copiedText: copiedText,
url: url,
activeAppName: activeAppName,
activeAppBundleIdentifier: activeAppBundleIdentifier
appContext: appContext
)

if (incognitoMode) {
Expand Down Expand Up @@ -345,11 +324,9 @@ class ClientManager {
userObjective: String,
userBio: String,
userLang: String,
copiedText: String,
copiedText: String?,
messages: [Message],
url: String,
activeAppName: String,
activeAppBundleIdentifier: String,
appContext: AppContext,
incognitoMode: Bool,
onboardingMode: Bool = false,
timeout: TimeInterval = 10,
Expand All @@ -364,11 +341,9 @@ class ClientManager {
userObjective: userObjective,
userBio: userBio,
userLang: userLang,
copiedText: copiedText,
// copiedText: copiedText,
messages: self?.sanitizeMessages(messages),
url: url,
activeAppName: activeAppName,
activeAppBundleIdentifier: activeAppBundleIdentifier,
appContext: appContext,
onboarding: onboardingMode
)

Expand Down Expand Up @@ -455,9 +430,7 @@ class ClientManager {

do {
var payloadCopy = payload
payloadCopy.url = ""
payloadCopy.activeAppName = ""
payloadCopy.activeAppBundleIdentifier = ""
payloadCopy.appContext = nil

let jsonData = try encoder.encode(payloadCopy)
if let jsonString = String(data: jsonData, encoding: .utf8) {
Expand Down
Loading