Skip to content

Commit

Permalink
Last adjustments
Browse files Browse the repository at this point in the history
  • Loading branch information
philippzagar committed Feb 26, 2024
1 parent fd7ac71 commit f4c8729
Show file tree
Hide file tree
Showing 27 changed files with 1,062 additions and 314 deletions.
13 changes: 6 additions & 7 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,17 @@ let package = Package(
products: [
.library(name: "SpeziFHIR", targets: ["SpeziFHIR"]),
.library(name: "SpeziFHIRHealthKit", targets: ["SpeziFHIRHealthKit"]),
.library(name: "SpeziFHIRInterpretation", targets: ["SpeziFHIRInterpretation"]),
.library(name: "SpeziFHIRLLM", targets: ["SpeziFHIRLLM"]),
.library(name: "SpeziFHIRMockPatients", targets: ["SpeziFHIRMockPatients"])
],
dependencies: [
.package(url: "https://github.com/apple/FHIRModels", .upToNextMinor(from: "0.5.0")),
.package(url: "https://github.com/StanfordBDHG/HealthKitOnFHIR", .upToNextMinor(from: "0.2.4")),
.package(url: "https://github.com/StanfordSpezi/Spezi", from: "1.1.0"),
.package(url: "https://github.com/StanfordSpezi/SpeziHealthKit.git", .upToNextMinor(from: "0.5.0")),
//.package(url: "https://github.com/StanfordSpezi/SpeziLLM.git", branch: "feat/structural-improvments"),
.package(path: "../SpeziLLM"),
.package(url: "https://github.com/StanfordSpezi/Spezi", from: "1.2.1"),
.package(url: "https://github.com/StanfordSpezi/SpeziHealthKit.git", .upToNextMinor(from: "0.5.1")),
.package(url: "https://github.com/StanfordSpezi/SpeziLLM.git", .upToNextMinor(from: "0.7.0")),
.package(url: "https://github.com/StanfordSpezi/SpeziStorage.git", from: "1.0.0"),
.package(url: "https://github.com/StanfordSpezi/SpeziChat.git", .upToNextMinor(from: "0.1.4")),
.package(url: "https://github.com/StanfordSpezi/SpeziChat.git", .upToNextMinor(from: "0.1.8")),
.package(url: "https://github.com/StanfordSpezi/SpeziSpeech.git", from: "1.0.0")
],
targets: [
Expand All @@ -53,7 +52,7 @@ let package = Package(
]
),
.target(
name: "SpeziFHIRInterpretation",
name: "SpeziFHIRLLM",
dependencies: [
.target(name: "SpeziFHIR"),
.product(name: "Spezi", package: "Spezi"),
Expand Down
190 changes: 0 additions & 190 deletions Sources/SpeziFHIRInterpretation/Resources/Localizable.xcstrings

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// This source file is part of the Stanford LLM on FHIR project
// This source file is part of the Stanford Spezi project
//
// SPDX-FileCopyrightText: 2023 Stanford University
//
Expand All @@ -19,18 +19,32 @@ struct FHIRGetResourceLLMFunction: LLMFunction {

private let fhirStore: FHIRStore
private let resourceSummary: FHIRResourceSummary
private let allResourcesFunctionCallIdentifier: [String]


@Parameter var resources: [String]


init(fhirStore: FHIRStore, resourceSummary: FHIRResourceSummary, allResourcesFunctionCallIdentifier: [String]) {
init(
fhirStore: FHIRStore,
resourceSummary: FHIRResourceSummary,
resourceCountLimit: Int,
allowedResourcesFunctionCallIdentifiers: Set<String>? = nil // swiftlint:disable:this discouraged_optional_collection
) {
self.fhirStore = fhirStore
self.resourceSummary = resourceSummary
self.allResourcesFunctionCallIdentifier = allResourcesFunctionCallIdentifier

_resources = Parameter(description: String(localized: "PARAMETER_DESCRIPTION"), enumValues: allResourcesFunctionCallIdentifier)
// Only take newest values of the health records
var allResourcesFunctionCallIdentifiers = Set(fhirStore.allResourcesFunctionCallIdentifier.suffix(resourceCountLimit))

// If identifiers are restricted, filter for only allowed function call identifiers of health records.
if let allowedResourcesFunctionCallIdentifiers {
allResourcesFunctionCallIdentifiers.formIntersection(allowedResourcesFunctionCallIdentifiers)
}

_resources = Parameter(
description: String(localized: "PARAMETER_DESCRIPTION"),
enumValues: Array(allResourcesFunctionCallIdentifiers)
)
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// This source file is part of the Stanford LLM on FHIR project
// This source file is part of the Stanford Spezi project
//
// SPDX-FileCopyrightText: 2023 Stanford University
//
Expand All @@ -22,13 +22,14 @@ private enum FHIRMultipleResourceInterpreterConstants {
}


/// Used to interpret multiple FHIR resources via a chat-based interface with an LLM.
@Observable
class FHIRMultipleResourceInterpreter {
public class FHIRMultipleResourceInterpreter {
static let logger = Logger(subsystem: "edu.stanford.spezi.fhir", category: "SpeziFHIRInterpretation")

private let localStorage: LocalStorage
private let llmRunner: LLMRunner
private let llmSchema: any LLMSchema
private var llmSchema: any LLMSchema
private let fhirStore: FHIRStore

var llm: (any LLMSession)?
Expand Down Expand Up @@ -64,7 +65,7 @@ class FHIRMultipleResourceInterpreter {
return
}

var llm = await llmRunner(with: llmSchema)
let llm = llmRunner(with: llmSchema)
// Read initial conversation from storage
if let storedContext: Chat = try? localStorage.read(storageKey: FHIRMultipleResourceInterpreterConstants.chat) {
llm.context = storedContext
Expand All @@ -81,7 +82,7 @@ class FHIRMultipleResourceInterpreter {
@MainActor
func queryLLM() {
guard let llm,
llm.context.last?.role == .user || !(llm.context.contains(where: { $0.role == .assistant }) ?? false) else {
llm.context.last?.role == .user || !(llm.context.contains(where: { $0.role == .assistant }) ) else {
return
}

Expand All @@ -100,6 +101,34 @@ class FHIRMultipleResourceInterpreter {
try localStorage.store(llm.context, storageKey: FHIRMultipleResourceInterpreterConstants.chat)
}
}

/// Change the `LLMSchema` used by the ``FHIRMultipleResourceInterpreter``.
public func changeLLMSchema(
openAIModel model: LLMOpenAIModelType,
resourceCountLimit: Int,
resourceSummary: FHIRResourceSummary,
allowedResourcesFunctionCallIdentifiers: Set<String>? = nil // swiftlint:disable:this discouraged_optional_collection
) {
self.llmSchema = LLMOpenAISchema(
parameters: .init(
modelType: model,
systemPrompts: [] // No system prompt as this will be determined later by the resource interpreter
)
) {
// FHIR interpretation function
FHIRGetResourceLLMFunction(
fhirStore: self.fhirStore,
resourceSummary: resourceSummary,
resourceCountLimit: resourceCountLimit,
allowedResourcesFunctionCallIdentifiers: allowedResourcesFunctionCallIdentifiers
)
}
self.llm = nil

Task { @MainActor in
await prepareLLM()
}
}
}


Expand All @@ -112,10 +141,12 @@ extension FHIRPrompt {
storageKey: "prompt.interpretMultipleResources",
localizedDescription: String(
localized: "Interpretation Prompt",
bundle: .module,
comment: "Title of the multiple resources interpretation prompt."
),
defaultPrompt: String(
localized: "Interpretation Prompt Content",
localized: "Multiple Resource Interpretation Prompt Content",
bundle: .module,
comment: "Content of the multiple resources interpretation prompt."
)
)
Expand Down
Loading

0 comments on commit f4c8729

Please sign in to comment.