Skip to content

Commit 3dd0e5e

Browse files
authored
Merge pull request #120 from rudrankriyam/stack/110-foundationlabcore
Create FoundationLabCore and define the first shared boundary
2 parents 637ba66 + 185a572 commit 3dd0e5e

File tree

14 files changed

+246
-0
lines changed

14 files changed

+246
-0
lines changed

FoundationLab.xcodeproj/project.pbxproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
0A21D7F12E518858004E8806 /* LiquidGlasKit in Frameworks */ = {isa = PBXBuildFile; productRef = 0A21D7F02E518858004E8806 /* LiquidGlasKit */; };
1111
0A5454AB2E1148A8002C2152 /* Foundation Lab.icon in Resources */ = {isa = PBXBuildFile; fileRef = 0A5454A72E1148A8002C2152 /* Foundation Lab.icon */; };
1212
0A979E842E1E5921008CFA37 /* FoundationModelsTools in Frameworks */ = {isa = PBXBuildFile; productRef = 0A979E832E1E5921008CFA37 /* FoundationModelsTools */; };
13+
0B0A11132ECB100100000001 /* FoundationLabCore in Frameworks */ = {isa = PBXBuildFile; productRef = 0B0A11122ECB100100000001 /* FoundationLabCore */; };
1314
F1B8C56E2E5B5A1C00XYZ123 /* LumoKit in Frameworks */ = {isa = PBXBuildFile; productRef = F1B8C56D2E5B5A1C00XYZ123 /* LumoKit */; };
1415
FA43F9412E13A16E00F24BCC /* HighlightSwift in Frameworks */ = {isa = PBXBuildFile; productRef = FA43F9402E13A16E00F24BCC /* HighlightSwift */; };
1516
/* End PBXBuildFile section */
@@ -55,6 +56,7 @@
5556
FA43F9412E13A16E00F24BCC /* HighlightSwift in Frameworks */,
5657
0A979E842E1E5921008CFA37 /* FoundationModelsTools in Frameworks */,
5758
0A21D7F12E518858004E8806 /* LiquidGlasKit in Frameworks */,
59+
0B0A11132ECB100100000001 /* FoundationLabCore in Frameworks */,
5860
F1B8C56E2E5B5A1C00XYZ123 /* LumoKit in Frameworks */,
5961
);
6062
runOnlyForDeploymentPostprocessing = 0;
@@ -119,6 +121,7 @@
119121
FA43F9402E13A16E00F24BCC /* HighlightSwift */,
120122
0A979E832E1E5921008CFA37 /* FoundationModelsTools */,
121123
0A21D7F02E518858004E8806 /* LiquidGlasKit */,
124+
0B0A11122ECB100100000001 /* FoundationLabCore */,
122125
F1B8C56D2E5B5A1C00XYZ123 /* LumoKit */,
123126
);
124127
productName = FoundationLab;
@@ -153,6 +156,7 @@
153156
0AC6037E2E1D5288002106F9 /* XCRemoteSwiftPackageReference "HighlightSwift" */,
154157
0A979E822E1E5921008CFA37 /* XCRemoteSwiftPackageReference "FoundationModelsTools" */,
155158
0A21D7EF2E518858004E8806 /* XCRemoteSwiftPackageReference "LiquidGlasKit" */,
159+
0B0A11112ECB100100000001 /* XCLocalSwiftPackageReference "FoundationLabCore" */,
156160
F1B8C56C2E5B5A1C00XYZ123 /* XCRemoteSwiftPackageReference "LumoKit" */,
157161
);
158162
preferredProjectObjectVersion = 77;
@@ -501,6 +505,13 @@
501505
};
502506
/* End XCConfigurationList section */
503507

508+
/* Begin XCLocalSwiftPackageReference section */
509+
0B0A11112ECB100100000001 /* XCLocalSwiftPackageReference "FoundationLabCore" */ = {
510+
isa = XCLocalSwiftPackageReference;
511+
relativePath = FoundationLabCore;
512+
};
513+
/* End XCLocalSwiftPackageReference section */
514+
504515
/* Begin XCRemoteSwiftPackageReference section */
505516
0A21D7EF2E518858004E8806 /* XCRemoteSwiftPackageReference "LiquidGlasKit" */ = {
506517
isa = XCRemoteSwiftPackageReference;
@@ -555,6 +566,11 @@
555566
package = 0A979E822E1E5921008CFA37 /* XCRemoteSwiftPackageReference "FoundationModelsTools" */;
556567
productName = FoundationModelsTools;
557568
};
569+
0B0A11122ECB100100000001 /* FoundationLabCore */ = {
570+
isa = XCSwiftPackageProductDependency;
571+
package = 0B0A11112ECB100100000001 /* XCLocalSwiftPackageReference "FoundationLabCore" */;
572+
productName = FoundationLabCore;
573+
};
558574
F1B8C56D2E5B5A1C00XYZ123 /* LumoKit */ = {
559575
isa = XCSwiftPackageProductDependency;
560576
package = F1B8C56C2E5B5A1C00XYZ123 /* XCRemoteSwiftPackageReference "LumoKit" */;

FoundationLabCore/Package.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// swift-tools-version: 6.2
2+
3+
import PackageDescription
4+
5+
let package = Package(
6+
name: "FoundationLabCore",
7+
platforms: [
8+
.iOS(.v26),
9+
.macOS(.v26),
10+
.visionOS(.v26)
11+
],
12+
products: [
13+
.library(
14+
name: "FoundationLabCore",
15+
targets: ["FoundationLabCore"]
16+
)
17+
],
18+
targets: [
19+
.target(
20+
name: "FoundationLabCore"
21+
),
22+
.testTarget(
23+
name: "FoundationLabCoreTests",
24+
dependencies: ["FoundationLabCore"]
25+
)
26+
]
27+
)

FoundationLabCore/README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# FoundationLabCore
2+
3+
`FoundationLabCore` is the first shared package for Foundation Lab.
4+
5+
Its job is narrow:
6+
7+
- define task-oriented capability boundaries
8+
- own shared request and result models
9+
- own domain-level errors
10+
- define provider protocols for concrete adapters
11+
12+
Its job is not to own delivery layers or UI concerns.
13+
14+
## Dependency rules
15+
16+
- `FoundationLabCore` must not import `SwiftUI`, `AppIntents`, or `ArgumentParser`.
17+
- `FoundationLabCore` must not own navigation, tabs, routes, or screen-local state.
18+
- App targets, App Intents adapters, and CLI adapters may depend on `FoundationLabCore`.
19+
- Concrete integrations with Apple frameworks or third-party SDKs belong in adapter packages, not here.
20+
21+
## Initial conventions
22+
23+
- `Capabilities/` contains task-oriented use case protocols and descriptors.
24+
- `Requests/` contains shared request models for core flows.
25+
- `Results/` contains shared result models and execution metadata.
26+
- `Errors/` contains domain-level errors surfaced by capabilities and providers.
27+
- `Providers/` contains abstraction seams that later packages implement.
28+
29+
This package is intentionally small. It creates the seam for later extraction work without moving major user-facing features yet.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import Foundation
2+
3+
public protocol CapabilityRequest: Sendable {}
4+
5+
public protocol CapabilityResult: Sendable {}
6+
7+
public struct CapabilityDescriptor: Sendable, Hashable {
8+
public let id: String
9+
public let displayName: String
10+
public let summary: String
11+
12+
public init(id: String, displayName: String, summary: String) {
13+
self.id = id
14+
self.displayName = displayName
15+
self.summary = summary
16+
}
17+
}
18+
19+
/// A task-oriented use case that can be shared by the app, App Intents, and CLI adapters.
20+
public protocol CapabilityUseCase: Sendable {
21+
associatedtype Request: CapabilityRequest
22+
associatedtype Result: CapabilityResult
23+
24+
static var descriptor: CapabilityDescriptor { get }
25+
26+
func execute(_ request: Request) async throws -> Result
27+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import Foundation
2+
3+
public enum FoundationLabCoreError: LocalizedError, Sendable, Equatable {
4+
case invalidRequest(String)
5+
case unavailableCapability(String)
6+
case providerFailure(String)
7+
case unsupportedEnvironment(String)
8+
9+
public var errorDescription: String? {
10+
switch self {
11+
case .invalidRequest(let message):
12+
return "Invalid request: \(message)"
13+
case .unavailableCapability(let message):
14+
return "Unavailable capability: \(message)"
15+
case .providerFailure(let message):
16+
return "Provider failure: \(message)"
17+
case .unsupportedEnvironment(let message):
18+
return "Unsupported environment: \(message)"
19+
}
20+
}
21+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import Foundation
2+
3+
public protocol StructuredGenerationProviding: Sendable {
4+
func generate<Output: Decodable & Sendable>(
5+
_ type: Output.Type,
6+
for request: StructuredGenerationRequest<Output>
7+
) async throws -> StructuredGenerationResult<Output>
8+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import Foundation
2+
3+
public protocol TextGenerationProviding: Sendable {
4+
func generateText(for request: TextGenerationRequest) async throws -> TextGenerationResult
5+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import Foundation
2+
3+
public enum InvocationSource: String, Sendable, Hashable, Codable {
4+
case app
5+
case appIntent
6+
case cli
7+
case automation
8+
case unknown
9+
}
10+
11+
public struct CapabilityInvocationContext: Sendable, Hashable, Codable {
12+
public let source: InvocationSource
13+
public let localeIdentifier: String?
14+
public let correlationID: UUID
15+
16+
public init(
17+
source: InvocationSource,
18+
localeIdentifier: String? = nil,
19+
correlationID: UUID = UUID()
20+
) {
21+
self.source = source
22+
self.localeIdentifier = localeIdentifier
23+
self.correlationID = correlationID
24+
}
25+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Foundation
2+
3+
public struct StructuredGenerationRequest<Output: Decodable & Sendable>: CapabilityRequest, Sendable {
4+
public let prompt: String
5+
public let systemPrompt: String?
6+
public let context: CapabilityInvocationContext
7+
8+
public init(
9+
prompt: String,
10+
systemPrompt: String? = nil,
11+
context: CapabilityInvocationContext
12+
) {
13+
self.prompt = prompt
14+
self.systemPrompt = systemPrompt
15+
self.context = context
16+
}
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import Foundation
2+
3+
public struct TextGenerationRequest: CapabilityRequest, Sendable, Hashable {
4+
public let prompt: String
5+
public let systemPrompt: String?
6+
public let context: CapabilityInvocationContext
7+
8+
public init(
9+
prompt: String,
10+
systemPrompt: String? = nil,
11+
context: CapabilityInvocationContext
12+
) {
13+
self.prompt = prompt
14+
self.systemPrompt = systemPrompt
15+
self.context = context
16+
}
17+
}

0 commit comments

Comments
 (0)