Health AI Platform Overview
Loop’s Health AI Platform combines structured patient data, declarative workflows, agent tools, research knowledge, and ML services into a single operating model.
At a high level, the platform answers five questions:
- What do we know about the patient?
- What logic should run next?
- What tools may act on that logic?
- What knowledge can enrich the response?
- What offline or statistical systems should support the experience?
Platform pillars
| Pillar | Repository surface | What it does |
|---|---|---|
| Workflow orchestration | packages/workflow-engine | Executes YAML or JSON workflow definitions |
| Clinical context | apps/patient-graph, packages/patient-graph-client | Provides patient profiles, labs, protocols, events, and more |
| Agent tools | apps/luna/src/lib/tools | Registers tool definitions for retrieval, actions, and support flows |
| Knowledge ingestion | packages/ai/src/ingestion | Extracts, chunks, and embeds research content |
| ML boundary | apps/ml-service, packages/ml-client | Exposes a Python service boundary for ML workloads |
End-to-end flow
Trigger or request
|
v
Workflow definition loaded
|
v
Patient context fetched from Patient Graph
|
v
Workflow steps evaluate conditions and actions
|
+--> Recommendations collected
|
+--> Tools invoked or prepared
|
+--> Knowledge / embeddings queried
|
v
Application or agent returns a responseWhere each concern lives
1. Workflow logic
The workflow engine is intentionally data-driven. A workflow is a definition, not handwritten orchestration code.
id: thyroid-assessment-v1
name: Thyroid Assessment
version: 1.0.0
steps:
- id: check-tsh
type: check_biomarker
action:
type: check_value
params:
biomarker: TSH
threshold: 2.5
operator: ">"
- id: recommend-selenium
type: recommend_supplement
condition: "check-tsh.result === true"
action:
type: recommend
params:
supplement: Selenium
dosage: 200mcgSee DSL Guide for the full shape.
2. Patient context
Patient data is fetched through the Patient Graph service or its typed client.
import { PatientGraphClientImpl } from '@loop/patient-graph-client';
const client = new PatientGraphClientImpl({
baseUrl: process.env.PATIENT_GRAPH_API_URL!,
getAuthToken: async () => process.env.PATIENT_GRAPH_API_KEY!,
});
const profile = await client.getPatientContext('user_123');See Patient Graph Integration.
3. Tool execution
Luna keeps a registry of named tools that an agent can use.
import { lunaTools, toolCategories } from '@/lib/tools';
const availableTools = Object.keys(lunaTools);
console.log(toolCategories['Product & Commerce']);
// ['product-search', 'create-cart', 'lookup-orders']See Tool Registry.
4. Research knowledge
Research ingestion converts papers into chunked, embedded records for retrieval workflows.
import { createResearchPaperIngestionPipeline } from '@loop/ai';
const pipeline = createResearchPaperIngestionPipeline({
apiKey: process.env.OPENAI_API_KEY!,
});See Research Engine.
5. ML service boundary
The Python service currently exposes a small HTTP surface and is consumed through @loop/ml-client.
import { MLClient } from '@loop/ml-client';
const ml = new MLClient({ baseUrl: 'http://localhost:8000' });
const health = await ml.healthCheck();See ML Layer.
Current-state architecture
This repository snapshot supports three levels of confidence:
Production-ready in this repo
- Workflow engine package
- Patient Graph service routes and repositories
- Patient Graph typed client
- Luna tool registration
- Embedding generation utilities
Present, but partially wired
- Research paper ingestion pipeline exists in
@loop/ai - Payload admin hook currently wraps a placeholder and reports ingestion as unavailable
Intentionally future-facing or deployment-specific
run_toolworkflow step is still a stubbed extension point- Junction is represented in environment and ops docs, but not as a fully implemented client in this tree
- ML service API is currently much smaller than the long-term vision
Design principles
Declarative first
Prefer configuration over branching application code.
const workflow = WorkflowEngine.load(definition);
const result = await workflow.execute({ patientId: 'p1', data: context });Typed boundaries
Services expose typed entry points where possible.
const result = await client.getPatientProtocols('user_123', {
status: 'active',
limit: 10,
});Explicit extension points
Not every interface is fully implemented yet, but the seams are visible and documented.
// Current behavior in the workflow engine:
// return { executed: true, toolId, params }That matters because docs should help contributors understand both what exists today and where future platform work should plug in.