Metadata-Version: 2.5
Name: lastsearch
Version: 1.3.2
Summary: Python SDK for LastSearch — Grounded Intelligence research infrastructure for AI agents
Project-URL: Homepage, https://lastsearch.ai
Project-URL: Documentation, https://lastsearch.ai/developers
Project-URL: Repository, https://github.com/lastsearch-hq/lastsearch
Project-URL: Discord, https://discord.gg/s8wj7tBAM
Author: LastSearch
License-Expression: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Keywords: agent-tools,agents,ai,ai-search,autogpt,citations,confidence-scoring,crewai,deep-search,evidence,fact-checking,grounded-intelligence,hallucination-prevention,langchain,lastsearch,llamaindex,llm,mcp,rag,research,search,verified-research,web-search
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.10
Requires-Dist: httpx>=0.25.0
Requires-Dist: pydantic>=2.0.0
Provides-Extra: crewai
Requires-Dist: crewai>=0.41.0; extra == 'crewai'
Provides-Extra: langchain
Requires-Dist: langchain-core>=0.2.0; extra == 'langchain'
Provides-Extra: verify
Requires-Dist: cryptography>=42.0; extra == 'verify'
Description-Content-Type: text/markdown

# lastsearch

**Reliable research infrastructure for AI agents.** Python SDK for [LastSearch](https://lastsearch.ai) — the research layer for LangChain, CrewAI, and custom agent pipelines.

## Install

```bash
pip install lastsearch
```

## Quick Start

```python
from lastsearch import LastSearch

client = LastSearch(api_key="ls_xxx")

# Research with citations
result = client.ask("What is quantum computing?")
print(result.answer)
print(f"Confidence: {result.confidence:.0%}")
for source in result.sources:
    print(f"  - {source.title}: {source.url}")

# Thorough mode — auto-retries if confidence < 60%
thorough = client.ask("What is quantum computing?", depth="thorough")

# Deep mode — multi-step agentic research with iterative gap analysis (requires LastSearch key + sign-in)
# Runs think→search→extract→evaluate cycles (up to 4 steps), 3x quota cost
deep = client.ask("Compare CRISPR approaches", depth="deep")
for step in deep.reasoning_steps or []:
    print(f"  Step {step.step}: {step.query} ({step.confidence:.0%})")

# Web search
results = client.search("latest AI news", limit=5)

# Page extraction
page = client.open("https://example.com")

# Structured extraction from a URL
extract = client.extract("https://example.com", query="pricing info")

# Compare raw LLM vs evidence-backed
compare = client.compare("Is Python faster than Rust?")

# Clarity — prompt mode (get enhanced prompts for your own LLM)
prompts = client.clarity("Write a blog post about quantum computing", mode="prompt")
print(prompts.system_prompt)  # Anti-hallucination system prompt
print(prompts.user_prompt)    # Rewritten user prompt with grounding cues
print(prompts.techniques)     # Which techniques were selected

# Clarity — answer mode (LLM answers with reduced hallucinations, no internet)
clarity = client.clarity("Write a blog post about quantum computing", mode="answer")
print(clarity.answer)         # LLM answer with reduced hallucinations
print(clarity.claims)         # Extracted claims (origin: "llm")
print(clarity.confidence)     # Confidence score

# Clarity — verified mode (LLM + web fusion for maximum accuracy)
verified = client.clarity("Explain CRISPR gene editing", mode="verified")
print(verified.answer)        # Fused answer (best of LLM + web sources)
print(verified.claims)        # Claims with origin: "confirmed", "llm", or "source"
print(verified.sources)       # Web sources used for verification

# Submit feedback to improve accuracy
client.feedback(result_id=result.share_id, rating="good")
```

## Async

```python
from lastsearch import AsyncLastSearch

async with AsyncLastSearch(api_key="ls_xxx") as client:
    result = await client.ask("What is quantum computing?")
    # Thorough mode works with async too
    thorough = await client.ask("What is quantum computing?", depth="thorough")
    # Deep mode — multi-step agentic research (requires LastSearch key + sign-in, 3x quota cost)
    deep = await client.ask("Complex research question", depth="deep")
```

## Streaming (REST API)

For real-time progress events, use the streaming endpoint directly:

```python
import httpx

with httpx.stream("POST", "https://lastsearch.ai/api/browse/answer/stream",
    json={"query": "What is quantum computing?"},
    headers={"X-API-Key": "ls_xxx"}
) as response:
    for line in response.iter_lines():
        if line.startswith("data: "):
            print(line[6:])
```

Events: `trace` (progress), `sources` (discovered early), `token` (streamed answer text), `result` (final answer), `done`.

## Research Memory (Sessions)

Persistent research sessions that accumulate knowledge across multiple queries. Later queries recall prior knowledge — faster, cheaper, more coherent.

> **Sessions require a LastSearch API key** (`api_key="ls_xxx"`) for identity and ownership. Get a free API key at [lastsearch.ai/dashboard](https://lastsearch.ai/dashboard).

```python
from lastsearch import LastSearch

client = LastSearch(api_key="ls_xxx")

# Create a session
session = client.session("wasm-research")

# Each query builds on previous knowledge
r1 = session.ask("What is WebAssembly?")
r2 = session.ask("How does WASM compare to JavaScript performance?")
# ^ r2 recalls WASM knowledge from r1, only searches for JS perf

# Query accumulated knowledge without new searches
recalled = session.recall("WASM")
for entry in recalled.entries:
    print(f"  {entry.claim} (from: {entry.origin_query})")

# Export all knowledge
knowledge = session.knowledge()

# Delete a session
session.delete()

# List all your sessions
sessions = client.list_sessions()

# Resume an existing session by ID
session = client.get_session("session-id-here")

# Share with other agents
share = session.share()
print(share.url)  # https://lastsearch.ai/session/share/abc123def456

# Another agent forks and continues the research
forked = client.fork_session(share.share_id)
```

Async sessions work the same way:

```python
async with AsyncLastSearch(api_key="ls_xxx") as client:
    session = await client.session("my-project")
    r1 = await session.ask("What is WASM?")
    r2 = await session.ask("WASM vs JS?")

    # Share and fork work async too
    share = await session.share()
    forked = await client.fork_session(share.share_id)
```

## Premium Features (with API Key)

Users with a LastSearch API key (`ls_xxx`) get enhanced verification:
- **Semantic re-ranking** — search results re-scored by semantic query-document relevance
- **Semantic reranking** — evidence matched by meaning, not just keywords
- **Multi-provider search** — parallel search across multiple sources for broader coverage
- **Multi-pass consistency** — claims cross-checked across independent extraction passes (in thorough mode)
- **Deep reasoning mode** — premium multi-step agentic research with iterative think-search-extract-evaluate cycles, gap analysis, and cross-step claim merging (up to 4 steps, targets 0.85 confidence, 3x quota cost, 100 deep queries/day). Falls back to thorough when quota is exhausted
- **Token streaming** — per-token answer delivery via SSE for real-time UI
- **Research Sessions** — persistent memory across queries

Free LastSearch key users get a generous daily quota (100 premium queries/day, or ~33 deep queries/day at 3x cost each). When exceeded, queries gracefully fall back to keyword verification (deep falls back to thorough) — still works, just basic matching. Quota resets every 24 hours. Check `client.last_quota` after any API call for current usage.

Sign in at [lastsearch.ai](https://lastsearch.ai) for a free LastSearch key to unlock premium features.

## Contradictions

Detect conflicts across sources on controversial topics:

```python
result = client.ask("Is coffee good for your health?", depth="thorough")
if result.contradictions:
    for c in result.contradictions:
        print(f"Conflict on '{c.topic}':")
        print(f"  A: {c.claim_a}")
        print(f"  B: {c.claim_b}")
```

## Enterprise Search Providers

Use your own data sources instead of — or alongside — public web search. Supports `elasticsearch`, `confluence`, and `custom` endpoints with optional `data_retention="none"`: results are not stored in our database or answer cache. Search-provider responses may be cached for up to 10 minutes, and our hosting provider keeps standard request logs.

```python
from lastsearch.models import SearchProviderConfig

# Using the typed model (snake_case fields)
provider = SearchProviderConfig(
    type="elasticsearch",
    endpoint="https://es.company.com/kb/_search",
    auth_header="Bearer token",
    index="docs",
)
result = client.ask("What is our refund policy?", search_provider=provider)

# Or pass a plain dict (camelCase keys, sent directly to API)
result = client.ask("What is our refund policy?", search_provider={
    "type": "elasticsearch",
    "endpoint": "https://es.company.com/kb/_search",
    "authHeader": "Bearer token",
    "index": "docs",
})

# Confluence
result = client.ask("PCI compliance?", search_provider={
    "type": "confluence",
    "endpoint": "https://company.atlassian.net/wiki/rest/api",
    "authHeader": "Basic base64-creds",
    "spaceKey": "ENG",
})

# data_retention="none": not stored in the database or answer cache (provider responses may be cached up to 10 min)
result = client.ask("Patient protocols", search_provider=SearchProviderConfig(
    type="elasticsearch",
    endpoint="https://es.hipaa.company.com/medical/_search",
    auth_header="Bearer token",
    data_retention="none",
))
```

## Framework Integrations

### LangChain

```bash
pip install langchain-lastsearch
```

```python
from langchain_lastsearch import LastSearchAnswerTool, LastSearchSearchTool

tools = [LastSearchAnswerTool(api_key="ls_xxx")]
```

### CrewAI

```bash
pip install crewai-lastsearch
```

```python
from crewai_lastsearch import LastSearchAnswerTool

researcher = Agent(tools=[LastSearchAnswerTool(api_key="ls_xxx")])
```

### LlamaIndex

```bash
pip install llamaindex-lastsearch
```

```python
from llamaindex_lastsearch import LastSearchAnswerTool

answer_tool = LastSearchAnswerTool(api_key="ls_xxx")
```

## Data, privacy and terms

This package sends your requests (queries, URLs and documents you ask it to verify) and your LastSearch API key to the hosted LastSearch API at lastsearch.ai. Queries and results are stored there and used, in aggregate and without identifiers, to improve verification, as described in the [Privacy Policy](https://lastsearch.ai/privacy). The package itself collects no telemetry. Use of the hosted API is subject to the [Terms](https://lastsearch.ai/terms).

LastSearch is a free, non-commercial passion project run by an individual developer. Answers, citations and confidence scores are AI-generated research, not professional advice; verify anything important against primary sources.
