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
10 changes: 5 additions & 5 deletions Foundation Lab/AdapterStudio/Services/AdapterProviderError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@ enum AdapterProviderError: LocalizedError {
var errorDescription: String? {
switch self {
case .directoryCreationFailed(let message):
String(localized: "Failed to prepare the adapter directory: \(message)")
String(localized: "The adapter folder couldn’t be prepared. \(message)")
case .directoryNotWritable(let path):
String(localized: "The adapter directory is not writable: \(path)")
String(localized: "Foundation Lab can’t write to the adapter folder at \(path). Choose another folder.")
case .invalidFileExtension(let url):
String(localized: "\"\(url.lastPathComponent)\" is not an .fmadapter package.")
case .copyFailed(let message):
String(localized: "Could not import the adapter: \(message)")
String(localized: "The adapter couldn’t be imported. \(message)")
case .loadFailed(let message):
String(localized: "Could not load the adapter: \(message)")
String(localized: "The adapter couldn’t be loaded. \(message)")
case .fileTooLarge(let size):
String(
localized: "The adapter is too large (\(ByteCountFormatter.string(fromByteCount: Int64(size), countStyle: .file)))."
)
case .sizeCalculationFailed(let url, let message):
String(localized: "Could not measure \"\(url.lastPathComponent)\": \(message)")
String(localized: "The size of \"\(url.lastPathComponent)\" couldn’t be read. \(message)")
}
}
}
Expand Down
47 changes: 8 additions & 39 deletions Foundation Lab/AdapterStudio/Views/AdapterStudioOutputView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,45 +23,14 @@ struct AdapterStudioOutputView: View {
)
.frame(maxWidth: .infinity, minHeight: 220)
} else {
ViewThatFits(in: .horizontal) {
HStack(alignment: .top, spacing: Spacing.large) {
AdapterStudioResponseColumn(
title: String(localized: "Base Model"),
subtitle: String(localized: "System language model"),
column: viewModel.baseColumn,
isActive: false
)

Divider()

AdapterStudioResponseColumn(
title: String(localized: "Custom Adapter"),
subtitle: viewModel.adapterContext?.metadata.fileName
?? String(localized: "Adapter"),
column: viewModel.adapterColumn,
isActive: false
)
}

VStack(spacing: Spacing.large) {
AdapterStudioResponseColumn(
title: String(localized: "Base Model"),
subtitle: String(localized: "System language model"),
column: viewModel.baseColumn,
isActive: false
)

Divider()

AdapterStudioResponseColumn(
title: String(localized: "Custom Adapter"),
subtitle: viewModel.adapterContext?.metadata.fileName
?? String(localized: "Adapter"),
column: viewModel.adapterColumn,
isActive: false
)
}
}
AdapterStudioResponseComparisonView(
baseSubtitle: String(localized: "System language model"),
adapterSubtitle: viewModel.adapterContext?.metadata.fileName
?? String(localized: "Adapter"),
baseColumn: viewModel.baseColumn,
adapterColumn: viewModel.adapterColumn,
isActive: false
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,16 @@ struct AdapterStudioResponseColumn: View {

ScrollView {
if let errorMessage = column.errorMessage {
Label(errorMessage, systemImage: "exclamationmark.triangle.fill")
Label {
Text(errorMessage)
.foregroundStyle(.primary)
} icon: {
Image(systemName: "exclamationmark.triangle.fill")
.foregroundStyle(.red)
}
.font(.callout)
.foregroundStyle(.red)
.frame(maxWidth: .infinity, alignment: .leading)
.accessibilityLabel("Error: \(errorMessage)")
} else if column.text.isEmpty {
HStack(spacing: Spacing.small) {
if isActive {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#if os(macOS)
import SwiftUI

struct AdapterStudioResponseComparisonView: View {
let baseSubtitle: String
let adapterSubtitle: String
let baseColumn: AdapterStudioColumnState
let adapterColumn: AdapterStudioColumnState
let isActive: Bool

var body: some View {
ViewThatFits(in: .horizontal) {
HStack(alignment: .top, spacing: Spacing.large) {
AdapterStudioResponseColumn(
title: String(localized: "Base Model"),
subtitle: baseSubtitle,
column: baseColumn,
isActive: isActive
)

Divider()

AdapterStudioResponseColumn(
title: String(localized: "Custom Adapter"),
subtitle: adapterSubtitle,
column: adapterColumn,
isActive: isActive
)
}

VStack(spacing: Spacing.large) {
AdapterStudioResponseColumn(
title: String(localized: "Base Model"),
subtitle: baseSubtitle,
column: baseColumn,
isActive: isActive
)

Divider()

AdapterStudioResponseColumn(
title: String(localized: "Custom Adapter"),
subtitle: adapterSubtitle,
column: adapterColumn,
isActive: isActive
)
}
}
}
}
#endif
63 changes: 25 additions & 38 deletions Foundation Lab/AdapterStudio/Views/AdapterStudioRunsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,46 +56,33 @@ struct AdapterStudioRunsView: View {
.foregroundStyle(.secondary)
}

ViewThatFits(in: .horizontal) {
HStack(alignment: .top, spacing: Spacing.large) {
AdapterStudioResponseColumn(
title: String(localized: "Base Model"),
subtitle: String(localized: "Fresh system model session"),
column: viewModel.baseColumn,
isActive: viewModel.isRunning
)

Divider()

AdapterStudioResponseColumn(
title: String(localized: "Custom Adapter"),
subtitle: viewModel.adapterContext?.metadata.fileName
?? String(localized: "No adapter loaded"),
column: viewModel.adapterColumn,
isActive: viewModel.isRunning
)
}

VStack(spacing: Spacing.large) {
AdapterStudioResponseColumn(
title: String(localized: "Base Model"),
subtitle: String(localized: "Fresh system model session"),
column: viewModel.baseColumn,
isActive: viewModel.isRunning
)

Divider()

AdapterStudioResponseColumn(
title: String(localized: "Custom Adapter"),
subtitle: viewModel.adapterContext?.metadata.fileName
?? String(localized: "No adapter loaded"),
column: viewModel.adapterColumn,
isActive: viewModel.isRunning
)
}
if hasComparisonOutput {
AdapterStudioResponseComparisonView(
baseSubtitle: String(localized: "Fresh system model session"),
adapterSubtitle: viewModel.adapterContext?.metadata.fileName
?? String(localized: "No adapter loaded"),
baseColumn: viewModel.baseColumn,
adapterColumn: viewModel.adapterColumn,
isActive: viewModel.isRunning
)
} else {
ContentUnavailableView(
"Ready to Compare",
systemImage: "square.split.2x1",
description: Text("Enter one prompt to inspect the base model and custom adapter side by side.")
)
.frame(maxWidth: .infinity, minHeight: 220)
}
}
}

private var hasComparisonOutput: Bool {
viewModel.isRunning
|| viewModel.lastResult != nil
|| !viewModel.baseColumn.text.isEmpty
|| !viewModel.adapterColumn.text.isEmpty
|| viewModel.baseColumn.errorMessage != nil
|| viewModel.adapterColumn.errorMessage != nil
}
Comment thread
cursor[bot] marked this conversation as resolved.
}
#endif
6 changes: 3 additions & 3 deletions Foundation Lab/AppIntents/AnalyzeNutritionIntent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import Foundation
import FoundationLabCore

struct AnalyzeNutritionIntent: AppIntent {
static let title: LocalizedStringResource = "Analyze Nutrition"
static let title: LocalizedStringResource = "Estimate Meal Nutrition"
static let description = IntentDescription(
"Analyzes meal nutrition using Foundation Lab's shared nutrition capability."
"Generates an approximate nutrition summary from a meal description."
)
static let openAppWhenRun = false

@Parameter(
title: "Meal Description",
requestValueDialog: IntentDialog("What meal should I analyze?")
requestValueDialog: IntentDialog("What meal should I estimate?")
)
var mealDescription: String

Expand Down
22 changes: 11 additions & 11 deletions Foundation Lab/AppIntents/AppIntentDestinations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ enum ExampleDestination: String, AppEnum, CaseIterable {
static let typeDisplayRepresentation = TypeDisplayRepresentation(name: "Example")

static let caseDisplayRepresentations: [ExampleDestination: DisplayRepresentation] = [
.basicChat: DisplayRepresentation(title: "One-shot"),
.basicChat: DisplayRepresentation(title: "One-Shot Prompt"),
.journaling: DisplayRepresentation(title: "Journaling"),
.creativeWriting: DisplayRepresentation(title: "Creative Writing"),
.structuredData: DisplayRepresentation(title: "Structured Data"),
.streamingResponse: DisplayRepresentation(title: "Streaming Response"),
.modelAvailability: DisplayRepresentation(title: "Model Availability"),
.generationGuides: DisplayRepresentation(title: "Generation Guides"),
.generationOptions: DisplayRepresentation(title: "Generation Options"),
.health: DisplayRepresentation(title: "Health Dashboard"),
.rag: DisplayRepresentation(title: "RAG Chat")
.health: DisplayRepresentation(title: "Health"),
.rag: DisplayRepresentation(title: "Document Q&A")
]

var exampleType: ExampleType {
Expand Down Expand Up @@ -126,16 +126,16 @@ enum SchemaDestination: String, AppEnum, CaseIterable {
static let typeDisplayRepresentation = TypeDisplayRepresentation(name: "Schema Example")

static let caseDisplayRepresentations: [SchemaDestination: DisplayRepresentation] = [
.basicObject: DisplayRepresentation(title: "Basic Object Schema"),
.arraySchema: DisplayRepresentation(title: "Array Schemas"),
.enumSchema: DisplayRepresentation(title: "Enum Schemas"),
.basicObject: DisplayRepresentation(title: "Basic Object"),
.arraySchema: DisplayRepresentation(title: "Arrays"),
.enumSchema: DisplayRepresentation(title: "Enumerations"),
.nestedObjects: DisplayRepresentation(title: "Nested Objects"),
.schemaReferences: DisplayRepresentation(title: "Schema References"),
.generationGuides: DisplayRepresentation(title: "Generation Guides"),
.generablePattern: DisplayRepresentation(title: "@Generable Pattern"),
.unionTypes: DisplayRepresentation(title: "Union Types"),
.formBuilder: DisplayRepresentation(title: "Dynamic Form Builder"),
.errorHandling: DisplayRepresentation(title: "Error Handling"),
.formBuilder: DisplayRepresentation(title: "Form Builder"),
.errorHandling: DisplayRepresentation(title: "Schema Errors"),
.invoiceProcessing: DisplayRepresentation(title: "Invoice Processing")
]

Expand Down Expand Up @@ -177,9 +177,9 @@ enum LanguageDestination: String, AppEnum, CaseIterable {

static let caseDisplayRepresentations: [LanguageDestination: DisplayRepresentation] = [
.languageDetection: DisplayRepresentation(title: "Language Detection"),
.multilingualResponses: DisplayRepresentation(title: "Multilingual Play"),
.sessionManagement: DisplayRepresentation(title: "Multiple Sessions"),
.productionExample: DisplayRepresentation(title: "Insights Example")
.multilingualResponses: DisplayRepresentation(title: "Multilingual Responses"),
.sessionManagement: DisplayRepresentation(title: "Language Sessions"),
.productionExample: DisplayRepresentation(title: "Localized App Pattern")
]

var languageExample: LanguageExample {
Expand Down
16 changes: 8 additions & 8 deletions Foundation Lab/AppIntents/FoundationLabAppShortcuts.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ nonisolated struct FoundationLabAppShortcuts: AppShortcutsProvider {
AppShortcut(
intent: AnalyzeNutritionIntent(),
phrases: [
"Analyze nutrition in \(.applicationName)",
"Check calories with \(.applicationName)"
"Estimate meal nutrition in \(.applicationName)",
"Get a meal estimate with \(.applicationName)"
],
shortTitle: LocalizedStringResource("Analyze Nutrition", table: "Localizable"),
shortTitle: LocalizedStringResource("Estimate Nutrition", table: "Localizable"),
systemImageName: "fork.knife"
)
AppShortcut(
Expand All @@ -58,7 +58,7 @@ nonisolated struct FoundationLabAppShortcuts: AppShortcutsProvider {
intent: QueryCalendarIntent(),
phrases: [
"Check my calendar in \(.applicationName)",
"Ask calendar with \(.applicationName)"
"Ask about my calendar in \(.applicationName)"
],
shortTitle: LocalizedStringResource("Query Calendar", table: "Localizable"),
systemImageName: "calendar"
Expand All @@ -76,7 +76,7 @@ nonisolated struct FoundationLabAppShortcuts: AppShortcutsProvider {
intent: GetCurrentLocationIntent(),
phrases: [
"Get my location in \(.applicationName)",
"Check location with \(.applicationName)"
"Check my location with \(.applicationName)"
],
shortTitle: LocalizedStringResource("Get Location", table: "Localizable"),
systemImageName: "location"
Expand All @@ -93,10 +93,10 @@ nonisolated struct FoundationLabAppShortcuts: AppShortcutsProvider {
AppShortcut(
intent: QueryHealthDataIntent(),
phrases: [
"Check health data in \(.applicationName)",
"Ask health data with \(.applicationName)"
"Read health data in \(.applicationName)",
"Ask \(.applicationName) about health data"
],
shortTitle: LocalizedStringResource("Query Health", table: "Localizable"),
shortTitle: LocalizedStringResource("Read Health Data", table: "Localizable"),
systemImageName: "heart.text.square"
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import FoundationLabCore
struct GenerateBookRecommendationIntent: AppIntent {
static let title: LocalizedStringResource = "Generate Book Recommendation"
static let description = IntentDescription(
"Generates a book recommendation using Foundation Lab's shared capability."
"Creates a structured book recommendation from your prompt."
)
static let openAppWhenRun = false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import FoundationLabCore
struct GenerateLocalizedResponseIntent: AppIntent {
static let title: LocalizedStringResource = "Generate Localized Response"
static let description = IntentDescription(
"Generates a response in one of the languages supported by Foundation Lab."
"Generates a response in a selected language supported by Foundation Models."
)
static let openAppWhenRun = false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import FoundationLabCore
struct GenerateWebPageSummaryIntent: AppIntent {
static let title: LocalizedStringResource = "Generate Web Page Summary"
static let description = IntentDescription(
"Summarizes a web page using Foundation Lab's shared web metadata capability."
"Summarizes the metadata available for a web page."
)
static let openAppWhenRun = false

Expand Down
2 changes: 1 addition & 1 deletion Foundation Lab/AppIntents/GetCurrentLocationIntent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import FoundationLabCore
struct GetCurrentLocationIntent: AppIntent {
static let title: LocalizedStringResource = "Get Current Location"
static let description = IntentDescription(
"Gets your current location using Foundation Lab's shared location capability."
"Returns your current location after you grant permission."
)
static let openAppWhenRun = true

Expand Down
2 changes: 1 addition & 1 deletion Foundation Lab/AppIntents/GetWeatherIntent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import FoundationLabCore
struct GetWeatherIntent: AppIntent {
static let title: LocalizedStringResource = "Get Weather"
static let description = IntentDescription(
"Gets the latest weather information using Foundation Lab's shared weather capability."
"Looks up current weather for a location."
)
static let openAppWhenRun = false

Expand Down
2 changes: 1 addition & 1 deletion Foundation Lab/AppIntents/ManageRemindersIntent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import FoundationLabCore
struct ManageRemindersIntent: AppIntent {
static let title: LocalizedStringResource = "Manage Reminders"
static let description = IntentDescription(
"Creates or manages reminders using Foundation Lab's shared reminders capability."
"Creates or updates reminders after you approve the change."
)
static let openAppWhenRun = true

Expand Down
Loading
Loading