Skip to content

Commit

Permalink
Better state handelling
Browse files Browse the repository at this point in the history
  • Loading branch information
philippzagar committed Feb 13, 2024
1 parent 12a59ea commit b5d6ccb
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 45 deletions.
12 changes: 7 additions & 5 deletions LLMonFHIR/FHIR Display/MultipleResourcesChatView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@ struct MultipleResourcesChatView: View {
let contextBinding = Binding { llm.context } set: { llm.context = $0 }
ChatView(
contextBinding,
disableInput: multipleResourceInterpreter.viewState == .processing
disableInput: llm.state.representation == .processing
)
.viewStateAlert(state: llm.state)
.onChange(of: llm.context) {
multipleResourceInterpreter.queryLLM()
if llm.state == .ready {
multipleResourceInterpreter.queryLLM()
}
}
} else {
ChatView(
Expand All @@ -47,7 +50,6 @@ struct MultipleResourcesChatView: View {
.toolbar {
toolbar
}
.viewStateAlert(state: $multipleResourceInterpreter.viewState)
.onAppear {
multipleResourceInterpreter.queryLLM()
}
Expand All @@ -58,7 +60,7 @@ struct MultipleResourcesChatView: View {

@MainActor @ToolbarContentBuilder private var toolbar: some ToolbarContent {

Check warning on line 61 in LLMonFHIR/FHIR Display/MultipleResourcesChatView.swift

View check run for this annotation

Codecov / codecov/patch

LLMonFHIR/FHIR Display/MultipleResourcesChatView.swift#L61

Added line #L61 was not covered by tests
ToolbarItem(placement: .cancellationAction) {
if multipleResourceInterpreter.viewState == .processing {
if multipleResourceInterpreter.llm?.state.representation == .processing {

Check warning on line 63 in LLMonFHIR/FHIR Display/MultipleResourcesChatView.swift

View check run for this annotation

Codecov / codecov/patch

LLMonFHIR/FHIR Display/MultipleResourcesChatView.swift#L63

Added line #L63 was not covered by tests
ProgressView()
} else {
Button("Close") {
Expand Down Expand Up @@ -92,7 +94,7 @@ struct MultipleResourcesChatView: View {
.accessibilityLabel(Text("Reset Chat"))
}
)
.disabled(multipleResourceInterpreter.viewState == .processing)
.disabled(multipleResourceInterpreter.llm?.state.representation == .processing)

Check warning on line 97 in LLMonFHIR/FHIR Display/MultipleResourcesChatView.swift

View check run for this annotation

Codecov / codecov/patch

LLMonFHIR/FHIR Display/MultipleResourcesChatView.swift#L97

Added line #L97 was not covered by tests
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class FHIRInterpretationModule: Module {
systemPrompt: nil // No system prompt as this will be determined later by the resource interpreter
)
) {
// FHIR interpretation function
FHIRInterpretationFunction(
fhirStore: self.fhirStore,
resourceSummary: self.resourceSummary,
Expand Down
70 changes: 30 additions & 40 deletions LLMonFHIR/FHIR Interpretation/FHIRMultipleResourceInterpreter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// SPDX-License-Identifier: MIT
//

import os
import Spezi
import SpeziFHIR
import SpeziFHIRInterpretation
Expand All @@ -23,13 +24,14 @@ private enum FHIRMultipleResourceInterpreterConstants {

@Observable
class FHIRMultipleResourceInterpreter {
static let logger = Logger(subsystem: "edu.stanford.bdhg", category: "LLMonFHIR")

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

@MainActor var viewState: ViewState = .idle
var llm: (any LLMSession)?


Expand All @@ -56,50 +58,38 @@ class FHIRMultipleResourceInterpreter {

@MainActor
func queryLLM() {
guard viewState == .idle, llm?.context.last?.role == .user || !(llm?.context.contains(where: { $0.role == .assistant }) ?? false) else {
guard llm?.context.last?.role == .user || !(llm?.context.contains(where: { $0.role == .assistant }) ?? false) else {

Check warning on line 61 in LLMonFHIR/FHIR Interpretation/FHIRMultipleResourceInterpreter.swift

View check run for this annotation

Codecov / codecov/patch

LLMonFHIR/FHIR Interpretation/FHIRMultipleResourceInterpreter.swift#L61

Added line #L61 was not covered by tests
return
}

Task {
do {
var llm: LLMSession
if let llmTemp = self.llm {
llm = llmTemp
} else {
llm = await llmRunner(with: llmSchema)
self.llm = llm
}

viewState = .processing

if llm.context.isEmpty {
llm.context.append(systemMessage: FHIRPrompt.interpretMultipleResources.prompt)
}

if let patient = fhirStore.patient {
llm.context.append(systemMessage: patient.jsonDescription)
}

print("The Multiple Resource Interpreter has access to \(fhirStore.llmRelevantResources.count) resources.")

do {
let stream = try await llm.generate()

for try await token in stream {
llm.context.append(assistantOutput: token)
}
} catch let error as LLMError {
llm.state = .error(error: error)
} catch {
llm.state = .error(error: LLMDefaultError.unknown(error))
}

try localStorage.store(llm.context, storageKey: FHIRMultipleResourceInterpreterConstants.chat)

viewState = .idle
} catch {
viewState = .error(error.localizedDescription)
var llm: LLMSession
if let llmTemp = self.llm {
llm = llmTemp
} else {
llm = await llmRunner(with: llmSchema)
self.llm = llm

Check warning on line 71 in LLMonFHIR/FHIR Interpretation/FHIRMultipleResourceInterpreter.swift

View check run for this annotation

Codecov / codecov/patch

LLMonFHIR/FHIR Interpretation/FHIRMultipleResourceInterpreter.swift#L66-L71

Added lines #L66 - L71 were not covered by tests
}

if llm.context.isEmpty {
llm.context.append(systemMessage: FHIRPrompt.interpretMultipleResources.prompt)

Check warning on line 75 in LLMonFHIR/FHIR Interpretation/FHIRMultipleResourceInterpreter.swift

View check run for this annotation

Codecov / codecov/patch

LLMonFHIR/FHIR Interpretation/FHIRMultipleResourceInterpreter.swift#L74-L75

Added lines #L74 - L75 were not covered by tests
}

if let patient = fhirStore.patient {
llm.context.append(systemMessage: patient.jsonDescription)

Check warning on line 79 in LLMonFHIR/FHIR Interpretation/FHIRMultipleResourceInterpreter.swift

View check run for this annotation

Codecov / codecov/patch

LLMonFHIR/FHIR Interpretation/FHIRMultipleResourceInterpreter.swift#L78-L79

Added lines #L78 - L79 were not covered by tests
}

Self.logger.debug("The Multiple Resource Interpreter has access to \(self.fhirStore.llmRelevantResources.count) resources.")

Check warning on line 82 in LLMonFHIR/FHIR Interpretation/FHIRMultipleResourceInterpreter.swift

View check run for this annotation

Codecov / codecov/patch

LLMonFHIR/FHIR Interpretation/FHIRMultipleResourceInterpreter.swift#L82

Added line #L82 was not covered by tests

guard let stream = try? await llm.generate() else {
return

Check warning on line 85 in LLMonFHIR/FHIR Interpretation/FHIRMultipleResourceInterpreter.swift

View check run for this annotation

Codecov / codecov/patch

LLMonFHIR/FHIR Interpretation/FHIRMultipleResourceInterpreter.swift#L84-L85

Added lines #L84 - L85 were not covered by tests
}

for try await token in stream {
llm.context.append(assistantOutput: token)

Check warning on line 89 in LLMonFHIR/FHIR Interpretation/FHIRMultipleResourceInterpreter.swift

View check run for this annotation

Codecov / codecov/patch

LLMonFHIR/FHIR Interpretation/FHIRMultipleResourceInterpreter.swift#L88-L89

Added lines #L88 - L89 were not covered by tests
}

try localStorage.store(llm.context, storageKey: FHIRMultipleResourceInterpreterConstants.chat)

Check warning on line 92 in LLMonFHIR/FHIR Interpretation/FHIRMultipleResourceInterpreter.swift

View check run for this annotation

Codecov / codecov/patch

LLMonFHIR/FHIR Interpretation/FHIRMultipleResourceInterpreter.swift#L92

Added line #L92 was not covered by tests
}
}
}
Expand Down

0 comments on commit b5d6ccb

Please sign in to comment.