Skip to main content

Parallel agent sensemaking tool — collaborative async data analysis with LLM threads

Project description

Latent Insights

Parallel-agent sensemaking for collaborative data analysis. For any uploaded dataset, the system discovers questions, spawns analytical threads, executes LLM orchestrated tool calls, and builds insights with you.

The agent is designed to follow steps from a sensemaking process such as foraging for evidence, framing the hypothesis, investigating the data, and synthesizing the results.

Install

pip install latent-insights

Quick start

OpenRouter (default)

export LLM_API_KEY=<your-key>

Ollama (local, free)

export LLM_PROVIDER=ollama

Override individual models if needed:

export LLM_PROVIDER=ollama
export MODEL_WORKER=gemma3:4b

As a library

from latent_insights import AppConfig
from latent_insights.core.llm import LLMClient
from latent_insights.core.queue import Queue
from latent_insights.core.state import StateStore
from latent_insights.core.tracing import TraceStore
from latent_insights.db.connection import Database
from latent_insights.orchestration.session import SessionFlow

config = AppConfig.from_env()
llm = LLMClient(
    api_key=config.llm_api_key,
    base_url=config.llm_base_url,
    app_name=config.app_name,
    app_url=config.app_url,
)
db = Database(data_dir=config.data_dir)
queue = Queue()
state = StateStore(data_dir=config.data_dir)
trace = TraceStore(data_dir=config.data_dir)

flow = SessionFlow(config, llm, db, queue, state, trace)
flow.create(session_id, "path/to/data.csv")

Development

git clone https://github.com/karthikbadam/latent-insights.git
cd latent-insights
uv sync --extra dev

# Run dev server with hot reload
uv run uvicorn latent_insights.main:app --reload

# Run tests
uv run pytest                    # all tests
uv run pytest -m "not live"      # skip API-calling tests
uv run ruff check .

Architecture

POST /api/sessions (upload CSV)
         │
         ▼
┌─────────────-────┐
│     Session      │
│  Profiler → Scout│──── schema summary + seed questions
└────────┬─────-───┘
         │ spawns N threads
         ▼
┌─────────────-────┐   ┌────────────-─────┐   ┌─────────────-────┐
│    Thread 1      │   │    Thread 2      │   │    Thread N      │
│                  │   │                  │   │                  │
│  ┌────────────┐  │   │  ┌────────────┐  │   │  ┌────────────┐  │
│  │Coordinator │◄─┤   │  │Coordinator │◄─┤   │  │Coordinator │◄─┤
│  │  (judge)   │  │   │  │  (judge)   │  │   │  │  (judge)   │  │
│  └─────┬──────┘  │   │  └─────┬──────┘  │   │  └─────┬──────┘  │
│        │ decide  │   │        │         │   │        │         │
│        ▼         │   │        ▼         │   │        ▼         │
│  ┌────────────┐  │   │  ┌────────────┐  │   │  ┌────────────┐  │
│  │   Worker   │  │   │  │   Worker   │  │   │  │   Worker   │  │
│  │  LLM+SQL   │  │   │  │  LLM+SQL   │  │   │  │  LLM+SQL   │  │
│  └────────────┘  │   │  └────────────┘  │   │  └────────────┘  │
│                  │   │                  │   │                  │
│  Steps: SCOPE    │   │  Steps: FORAGE   │   │  Steps: FRAME    │
│  → FORAGE        │   │  → INTERROGATE   │   │  → INTERROGATE   │
│  → FRAME         │   │  → SYNTHESIZE    │   │  → SYNTHESIZE    │
│  → INTERROGATE   │   │  ✓ DONE          │   │  ? STUCK (human) │
│  → SYNTHESIZE    │   │                  │   │                  │
│  ✓ DONE          │   │                  │   │                  │
└────────────────-─┘   └───────────────-──┘   └───────────────-──┘
         │                    │                       │
         └────────────────────┴───────────────────────┘
                              │
                    GET /api/sessions/{id}/events (SSE)
                    ← llm_call, tool_call, step, complete

Sensemaking moves

Move Purpose
SCOPE Define data slice, narrow to relevant subset
FORAGE Exploratory analysis — distributions, correlations, outliers
FRAME Propose tentative hypothesis as testable claim
INTERROGATE Stress-test the frame — contradictions, confounds
SYNTHESIZE Thread conclusion — finding, confidence, limitations

The coordinator picks moves freely based on data — no fixed order.

API

Endpoint Description
GET /health Health check
POST /api/sessions Create session (upload CSV + profile + scout + spawn threads)
GET /api/sessions List all sessions with metadata and thread counts
GET /api/sessions/{id} Full session state with threads and steps
POST /api/sessions/{id}/threads Create custom thread with a question
POST /api/sessions/{id}/continue Resume stuck threads + scout new questions
GET /api/threads/{id} Get single thread with steps and events
POST /api/threads/{id}/messages Reply to stuck thread, resuming it
GET /api/sessions/{id}/events SSE event stream (llm_call, tool_call, step, complete)
GET /api/system/stats Session and thread counts

Per-session config

POST /api/sessions accepts optional per-session overrides via a config object. All fields are optional — omitted fields use server defaults from environment variables.

curl -X POST http://localhost:8000/api/sessions \
  -F "file=@data/samples/cars.csv" \
  -F 'config={"max_threads": 20, "num_scout_seed_questions": 12, "initial_questions": ["What is an interesting visual insight in this dataset?", "What factors most influence fuel efficiency?", "Are there regional differences in car specifications?"]}'

Available config fields:

Field Type Description
model_profiler string Model for dataset profiling
model_scout string Model for question discovery
model_coordinator string Model for thread coordination
model_worker string Model for SQL analysis
model_worker_fallback string Fallback model after worker retries
temp_profiler float Temperature for profiler
temp_scout float Temperature for scout
temp_coordinator float Temperature for coordinator
temp_worker float Temperature for worker
max_threads int Cap on total threads spawned
max_worker_retries int Worker retries before fallback model
max_consecutive_errors int SQL errors before forcing summary
max_repeated_moves int Repeated coordinator moves before abort
llm_timeout float LLM call timeout in seconds
num_scout_seed_questions int Number of questions scout should discover
initial_questions string[] Seed questions to start alongside scout

Publishing to PyPI

# Build the package
uv build

# Publish (requires PyPI API token)
uv publish

# Or test with TestPyPI first
uv publish --publish-url https://test.pypi.org/legacy/

Docs

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

latent_insights-0.1.1.tar.gz (2.3 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

latent_insights-0.1.1-py3-none-any.whl (57.1 kB view details)

Uploaded Python 3

File details

Details for the file latent_insights-0.1.1.tar.gz.

File metadata

  • Download URL: latent_insights-0.1.1.tar.gz
  • Upload date:
  • Size: 2.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.4

File hashes

Hashes for latent_insights-0.1.1.tar.gz
Algorithm Hash digest
SHA256 85a105aa6ff2868d1dc5dade52b722130c86fb9bda3b2eb71d6ca694c3de8087
MD5 0753bb16a9e5e39ddf79eafce9927a1a
BLAKE2b-256 55bae63453d06aa63ec8716b4d55f0c55bba97007153433f62f197420dd34541

See more details on using hashes here.

File details

Details for the file latent_insights-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for latent_insights-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 863499164f55981d2b316fbe5a4832581ac85a0e93bdec3bf5ebd0bc64dfcfbe
MD5 8da1677478fd58af8bc4ee49bffa8ebe
BLAKE2b-256 055b2af3939fcabece490a010495592b0706f754a11b514ed68bdf0514b3c4f7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page