Skip to content
Closed
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
144 changes: 144 additions & 0 deletions skills/medical-entity-extractor/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
---
name: medical-entity-extractor
description: Extract medical entities (symptoms, medications, lab values, diagnoses) from patient messages.
license: MIT
metadata:
author: "NAPSTER AI"
maintainer: "NAPSTER AI"
openclaw:
requires:
bins: []
---

# Medical Entity Extractor

Extract structured medical information from unstructured patient messages.

## What This Skill Does

1. **Symptom Extraction**: Identifies symptoms, severity, duration, and progression
2. **Medication Extraction**: Finds medication names, dosages, frequencies, and side effects
3. **Lab Value Extraction**: Parses lab results, vital signs, and measurements
4. **Diagnosis Extraction**: Identifies mentioned diagnoses and conditions
5. **Temporal Extraction**: Captures when symptoms started, how long they've lasted
6. **Action Items**: Identifies requested actions (appointments, refills, questions)

## Input Format

```json
[
{
"id": "msg-123",
"priority_score": 78,
"priority_bucket": "P1",
"subject": "Medication side effects",
"from": "patient@example.com",
"date": "2026-02-27T10:30:00Z",
"body": "I've been feeling dizzy since starting the new blood pressure medication (Lisinopril 10mg) three days ago. My BP this morning was 145/92."
}
]
```

## Output Format

```json
[
{
"id": "msg-123",
"entities": {
"symptoms": [
{
"name": "dizziness",
"severity": "moderate",
"duration": "3 days",
"onset": "since starting new medication"
}
],
"medications": [
{
"name": "Lisinopril",
"dosage": "10mg",
"frequency": null,
"context": "new medication"
}
],
"lab_values": [
{
"type": "blood_pressure",
"value": "145/92",
"unit": "mmHg",
"timestamp": "this morning"
}
],
"diagnoses": [
{
"name": "hypertension",
"context": "implied by blood pressure medication"
}
],
"action_items": [
{
"type": "medication_review",
"reason": "possible side effect (dizziness)"
}
]
},
"summary": "Patient reports dizziness after starting Lisinopril 10mg 3 days ago. BP elevated at 145/92. Possible medication side effect requiring review."
}
]
```

## Entity Types

### Symptoms
- Name, severity (mild/moderate/severe), duration, onset, progression (improving/stable/worsening)

### Medications
- Name, dosage, frequency, route, context (new/existing/stopped)

### Lab Values
- Type (BP, glucose, cholesterol, etc.), value, unit, timestamp, normal range

### Diagnoses
- Name, context (confirmed/suspected/ruled out)

### Vital Signs
- Temperature, heart rate, respiratory rate, oxygen saturation, blood pressure

### Action Items
- Type (appointment, refill, question, callback), urgency, reason

## Medical Terminology Handling

The skill recognizes:
- Common abbreviations (BP, HR, RR, O2 sat, etc.)
- Brand and generic medication names
- Lay terms for medical conditions ("sugar" → diabetes, "heart attack" → MI)
- Temporal expressions ("since yesterday", "for the past week")

## Integration

This skill can be invoked via the OpenClaw CLI:

```bash
openclaw skill run medical-entity-extractor --input '[{"id":"msg-1","priority_score":78,...}]' --json
```

Or programmatically:

```typescript
const result = await execFileAsync('openclaw', [
'skill', 'run', 'medical-entity-extractor',
'--input', JSON.stringify(scoredMessages),
'--json'
]);
```

**Recommended Model**: Claude Sonnet 4.5 (`openclaw models set anthropic/claude-sonnet-4-5`)

## Privacy & Security

- All processing happens locally via OpenClaw
- No data is sent to external services (except Claude API for LLM processing)
- Extracted entities remain in your local environment

108 changes: 108 additions & 0 deletions skills/medical-priority-scorer/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
---
name: medical-priority-scorer
description: Score medical messages using urgency, sentiment, and patient context to produce priority rankings (P1/P2/P3).
license: MIT
metadata:
author: "NAPSTER AI"
maintainer: "NAPSTER AI"
openclaw:
requires:
bins: []
---

# Medical Priority Scorer

Produce deterministic priority scores for medical messages without mutating any state.

## Quick Triggers

- Rank messages by medical urgency for callback priority
- Classify messages into P1/P2/P3 queue
- Score follow-up priority from triaged messages

## Recommended Chain

`medical-triage -> medical-priority-scorer -> medical-entity-extractor`

## Execute Workflow

1. Accept input from medical-triage containing triaged messages
2. Score each message with:
- `urgency_score` in range `[0, 1]` (based on triage category)
- `sentiment_score` in range `[-1, 1]` (anxiety, distress, frustration)
- `recency_score` in range `[0, 1]` (how recent the message is)
- `patient_context_score` in range `[0, 1]` (chronic conditions, known patient)
3. Compute `priority_score` on a 0-100 scale:
- `priority_score = 100 * (0.50*urgency_score + 0.25*sentiment_score_risk + 0.15*recency_score + 0.10*patient_context_score)`
- `sentiment_score_risk = max(0, -sentiment_score)` (negative sentiment = higher risk)
4. Assign buckets:
- `P1` for `priority_score >= 75` (immediate attention)
- `P2` for `priority_score >= 50 and < 75` (same-day)
- `P3` for `< 50` (routine)
5. Produce plain-language `evidence` tokens that explain the score

## Input Format

```json
[
{
"id": "msg-123",
"category": "urgent",
"subject": "Medication side effects",
"from": "patient@example.com",
"date": "2026-02-27T10:30:00Z",
"body": "I've been feeling dizzy since starting the new medication..."
}
]
```

## Output Format

```json
[
{
"id": "msg-123",
"priority_score": 78,
"priority_bucket": "P1",
"urgency_score": 0.8,
"sentiment_score": -0.4,
"recency_score": 1.0,
"patient_context_score": 0.6,
"evidence": "Urgent triage category + negative sentiment (concern) + very recent message + known patient"
}
]
```

## Enforce Boundaries

- Never write to databases or files
- Never send messages or trigger outbound channels
- Never create reminders or execute actions
- Never bypass routing or approvals

## Handle Errors

1. Reject schema-invalid inputs
2. Return field-level reasons when scoring cannot be computed
3. Fail closed if required scoring features are missing

## Integration

This skill can be invoked via the OpenClaw CLI:

```bash
openclaw skill run medical-priority-scorer --input '[{"id":"msg-1","category":"urgent",...}]' --json
```

Or programmatically:

```typescript
const result = await execFileAsync('openclaw', [
'skill', 'run', 'medical-priority-scorer',
'--input', JSON.stringify(triagedMessages),
'--json'
]);
```

**Recommended Model**: Claude Sonnet 4.5 (`openclaw models set anthropic/claude-sonnet-4-5`)

115 changes: 115 additions & 0 deletions skills/medical-triage/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
---
name: medical-triage
description: Classify medical messages (emails, iMessages) as critical, urgent, or routine based on medical urgency indicators.
license: MIT
metadata:
author: "NAPSTER AI"
maintainer: "NAPSTER AI"
openclaw:
requires:
bins: []
---

# Medical Triage

Classify medical messages into priority categories based on urgency indicators, symptoms, and patient context.

## Categories

| Icon | Category | Description |
|------|----------|-------------|
| 🔴 | `critical` | Life-threatening symptoms, emergency keywords, severe pain |
| 🟡 | `urgent` | Needs same-day attention, worsening symptoms, medication issues |
| 🟢 | `routine` | Follow-ups, general questions, appointment requests |

## How It Works

This skill analyzes message content for:
- **Emergency keywords**: chest pain, difficulty breathing, severe bleeding, etc.
- **Symptom severity**: pain scale, duration, progression
- **Patient context**: chronic conditions, medications, recent procedures
- **Temporal urgency**: "right now", "getting worse", "can't wait"

## Input Format

The skill expects a JSON array of messages:

```json
[
{
"id": "msg-123",
"subject": "Chest pain",
"from": "patient@example.com",
"date": "2026-02-27T10:30:00Z",
"body": "I've been having chest pain for the last hour..."
}
]
```

## Output Format

Returns a JSON array with triage results:

```json
[
{
"id": "msg-123",
"category": "critical",
"reason": "Chest pain mentioned - potential cardiac emergency",
"confidence": 0.95
}
]
```

## Usage

This skill is designed to be invoked programmatically via OpenClaw's skill execution API.

## Medical Urgency Indicators

### Critical (🔴)
- Chest pain, pressure, or tightness
- Difficulty breathing or shortness of breath
- Severe bleeding
- Loss of consciousness
- Stroke symptoms (FAST: Face, Arms, Speech, Time)
- Severe allergic reaction
- Suicidal ideation

### Urgent (🟡)
- High fever (>103°F / 39.4°C)
- Persistent vomiting or diarrhea
- Medication side effects
- Worsening chronic condition
- Moderate pain (7-8/10)
- Infection signs (redness, swelling, pus)
- Mental health crisis

### Routine (🟢)
- Appointment requests
- Prescription refills
- General health questions
- Follow-up on stable conditions
- Lab result questions
- Mild symptoms (<3 days)

## Integration

This skill can be invoked via the OpenClaw CLI:

```bash
openclaw skill run medical-triage --input '[{"id":"msg-1","subject":"...","body":"..."}]' --json
```

Or programmatically:

```typescript
const result = await execFileAsync('openclaw', [
'skill', 'run', 'medical-triage',
'--input', JSON.stringify(messages),
'--json'
]);
```

**Recommended Model**: Claude Sonnet 4.5 (`openclaw models set anthropic/claude-sonnet-4-5`)