PULSE: Agentic Investigation with Passive Sensing for Proactive Affective Intervention in Cancer Survivorship
This repository contains the research code accompanying the IMWUT submission "PULSE: Agentic Investigation with Passive Sensing for Proactive Affective Intervention in Cancer Survivorship." It implements the full prediction pipeline described in the paper: an LLM agent that actively investigates passively sensed smartphone data to predict momentary affect and intervention availability in cancer survivors.
The study dataset is not included (see Data). The code, prompts, tool definitions, and evaluation pipeline are released verbatim so that the method can be inspected, audited, and applied to other longitudinal sensing datasets.
PULSE gives an LLM eight sensing-query tools exposed over the Model Context Protocol (MCP). Across multiple turns (ReAct-style, up to 16 tool-use turns, typically 6–12), the model selects modalities and lookback windows, requests personal-baseline comparisons, retrieves outcome-labeled cases, and returns predictions for study-defined affect and availability targets.
All inference runs through the claude CLI; the paper's experiments used
Claude Sonnet 4.6 (claude-sonnet-4-6). Each prediction launches a fresh MCP
server subprocess with the participant ID and EMA timestamp baked in, so
temporal restriction is enforced in deterministic data-access code: everything
served to the model is strictly before the EMA timestamp.
The paper evaluates a 2×2 design (architecture × current-diary input) plus a diary-only baseline. Internal code aliases appear throughout the source and in CLI arguments.
| Paper name | Internal | Architecture | Current-diary input |
|---|---|---|---|
| Struct-Sense | v1 |
structured single-pass | no |
| Auto-Sense | v2 |
agentic multi-turn | no |
| Struct-Multi | v3 |
structured single-pass | yes |
| Auto-Multi | v4 |
agentic multi-turn | yes |
| CALLM | callm |
diary-only LLM baseline (TF-IDF cross-user retrieval + longitudinal memory) | yes |
- Structured conditions assemble a sensing summary (up to the EMA timestamp), a trait profile, a memory document, and outcome-labeled peer examples into a single prompt, answered in one LLM call.
- Agentic conditions provide the user profile, the current diary entry (Auto-Multi only), and the eight MCP tools, then run a multi-turn investigation loop.
| Tool | Signature (defaults) | Returns |
|---|---|---|
get_daily_summary |
(date, lookback_days=0..7) |
Natural-language summary of a day's behavioral patterns, with optional multi-day lookback. |
get_behavioral_timeline |
(date, segment_hours=1..6) |
Chronological reconstruction of the day before the EMA. |
query_sensing |
(modality, hours_before_ema=1..48, hours_duration=1..24, granularity) |
Aggregates for one modality (GPS, motion, screen, keyboard, music, light). |
query_raw_events |
(modality, hours_before_ema, hours_duration, max_events=30) |
Raw event stream (app sessions, screen locks, activity transitions, typing sessions). |
compare_to_baseline |
(modality, feature, current_value=None, hours_before_ema=1) |
Current value (auto-fetched when omitted) vs. time-of-day-specific personal mean/SD, z-score, and qualitative bands at |z| = 0.5, 1, 2. |
get_receptivity_history |
(lookback_days=14) |
Prior numeric regulation-desire scores and availability labels. |
find_similar_days |
(top_k=3) |
Same-user past days by cosine similarity over daily behavioral fingerprints, with prior desire/availability and diary snippets. |
find_peer_cases |
(search_mode="text"|"sensing", query_text="", top_k=10, max 20) |
Outcome-labeled cases from other participants, via TF-IDF diary similarity (text mode, using query_text) or z-scored sensing-fingerprint cosine similarity. The current participant is excluded from the peer database; non-positive-similarity matches are omitted. |
Each prediction returns:
- Three continuous scores: PANAS positive affect (0–30), PANAS negative affect (0–30), and emotion-regulation desire (0–10).
- Sixteen binary indicators: individualized PA/NA states, discrete emotions, interaction quality, pain, future outlook, ER-desire state, and stated intervention availability.
- A reasoning trace and a confidence value in [0, 1].
The paper focuses on four targets: PA_State, NA_State, ER-desire state,
and INT_availability. As reported in the paper, Auto-Multi reaches 0.743
balanced accuracy on emotion-regulation desire with the current diary and
Auto-Sense 0.713 on stated availability without it (see paper).
As the agent processes a user's entries chronologically, a lightweight LLM
call (claude CLI, haiku) writes a 1–2 sentence reflection after each
prediction. The reflection sees the investigation summary, the prediction,
and only an EMA-derived binary composite (elevated regulation desire AND
stated availability) — never the component labels separately, and never the
affect scores. The accumulated reflection document is passed in full at
subsequent entries.
The --ablate-memory reflections flag reproduces the paper's ablation, which
removes only the reflection document.
All prompts are released verbatim:
src/agent/cc_agent.py— agentic conditions (Auto-Sense, Auto-Multi).src/think/prompts.py— structured conditions and CALLM.src/simulation/simulator.py— the session-memory reflection prompt.
The BUCS study dataset (407 adult cancer survivors, 5 weeks, 3 daily EMAs, passive smartphone sensing) is not distributed due to IRB restrictions. To run the pipeline on your own data, reproduce the following layout:
data/processed/
├── splits/
│ └── group_{1..5}_{train,test}.csv # EMA entries + labels
├── hourly/
│ └── {modality}/{pid}_{modality}_hourly.parquet
├── events/
│ └── {modality}_events/...
├── memory_documents/
│ └── user_{id}_memory.txt
└── filtered/
└── {pid}_daily_filtered.parquet # per-EMA truncated daily features
# used for peer sensing fingerprints
Raw BUCS CSVs are located via the PULSE_RAW_DATA_DIR environment variable
(default: data/raw).
Warning — temporal leakage. Memory documents must be generated only from data available before the evaluation period. Full-trajectory summaries would leak future information into the prediction context and invalidate the evaluation.
Requirements:
- Python >= 3.11
- The
claudeCLI, installed and authenticated - A Python environment with
mcpandpandasfor the MCP server (setPULSE_MCP_PYTHONto override which interpreter the server uses)
pip install -e .Dependencies: pandas, numpy, scikit-learn, pyarrow, mcp.
Environment variables:
| Variable | Purpose | Default |
|---|---|---|
PULSE_MCP_PYTHON |
Python interpreter used to launch the MCP server | current interpreter |
PULSE_TOOL_LOG_DIR |
Directory for tool-call JSONL logs | outputs/tool_logs |
PULSE_RAW_DATA_DIR |
Location of raw BUCS CSVs | data/raw |
PULSE_EMA_GUARD_MINUTES |
Guard window before each EMA in which keyboard events are withheld from raw-event queries (self-report typed into the survey app is not passive sensing) | 10 |
Run a single condition for selected participants:
python scripts/run_experiments.py --conditions auto-multi --users 71,119 --model claude-sonnet-4-6Run all conditions:
python scripts/run_experiments.py --conditions all --users <ids>Reproduce the session-memory ablation:
python scripts/run_experiments.py --conditions auto-multi --ablate-memory reflections ...Evaluate and compare conditions:
python scripts/evaluate_results.py --results-dir outputs/experiments --compare auto-multi,struct-multisrc/
├── agent/ # agentic + structured agents
├── sense/ # query engine + MCP server (the eight tools)
├── simulation/ # experiment runner + session-memory reflection
├── remember/ # TF-IDF + multimodal retrievers
├── think/ # prompts, CLI client, output parser
├── data/ # loaders, schema, EMA alignment
├── evaluation/ # balanced-accuracy metrics, reports
└── utils/
configs/
└── prediction_schema.json
scripts/ # run_experiments.py, evaluate_results.py
PULSE is a prediction layer only; it is not a clinical intervention or diagnostic system. All results in the paper come from retrospective evaluation on previously collected study data. See the paper for the full ethics discussion.
@article{pulse2026,
title = {PULSE: Agentic Investigation with Passive Sensing for Proactive
Affective Intervention in Cancer Survivorship},
author = {Anonymous},
journal = {Proceedings of the ACM on Interactive, Mobile, Wearable and
Ubiquitous Technologies (IMWUT)},
year = {2026},
note = {Details upon publication}
}MIT — see LICENSE.