v0.2.13

longbridge/gpui-kitv0.2.13Sep 1, 2026by github-actions[bot]

AI Summary

Enhances the streaming chat experience by visualizing the process (thinking, tool calls) and reduces LiteLLM noise in the terminal.

Key Highlights

  • Streamed `chat()` weaves process information into the text by default.
  • New `ChatProcessOptions` dict allows selecting parts like `thinking` and `max_chars`.
  • New `ChatStream.events` property provides full machine-readable typed data.
  • LiteLLM's terminal noise (like the 'Provider List' banner) is silenced.

New Features

  • Managed cloud streams now parse tool-call lines from chunk tags.
  • Usage accounting and prompt-cache continuity across turns.
  • Query-cost charts added to the README.

Full Release Notes

- The **PageIndex SDK**, **local** or **cloud** — vectorless, reasoning-based RAG, end to end.
- **Much faster indexing** — the **PageIndex Flash** engine gets the tree from layout stats: no LLM involved for the structure generation itself, LLMs only write the node summaries, and tree expansion proposes a wave of nodes concurrently.

```python
client = PageIndexClient()
client.submit_document("report.pdf")
client.chat("What does the report conclude?")
```

Index, to chat, to agent integration, one client.
Local mode needs no server, no vector DB, no PageIndex API key.

## Highlights

- **Flash engine**: the local default (`mode="standard"` keeps the classic LLM pipeline). Embedded bookmarks are consumed when trustworthy, and tree optimization is on by default — `optimize="merge"` for the deterministic LLM-free pass, `"full"` (default) adds LLM expand, which runs a wave of nodes concurrently instead of one round-trip at a time.
- **One complete surface, local and cloud**: `PageIndexLocalClient(storage_path=...)` is the same client as cloud — submit, tree, page content, chat, and agent tools all present in both modes, so code moves between them unchanged.
- **Cloud documents, your own model**: `api_key` decides where your documents live; a configured chat model decides who answers — and the two combine. `PageIndexClient(api_key="pi-...", chat_model="openai/gpt-5.2")` runs the same in-process document-QA engine over the live cloud tool set. Page content flows through your process to your provider on your credentials; `doc_id` targets at the prompt level; `enable_citations` stays with the managed chat.
- **Agent integration**: the cloud MCP tool contract, in-process — `client.agent_tools()` (plain functions), `as_openai_tools()`, `as_anthropic_tools()`, `as_claude_mcp()`, plus one-call `openai_agent_config()` / `anthropic_runner_config()` / `claude_agent_config()` bundles and `agent_instructions()` for the system prompt. Cloud clients get the live server tool set over the MCP bridge (read-only endpoint by default); local clients get the in-process subset with the same schemas and envelopes — agent prompts port unchanged.
- **Chat surfaces**: `chat()` — question in, answer out, on any backend, and `chat(stream=True)` shows the run as it happens, thinking and tool calls woven into the text; `chat_completions()` / `responses()` / `messages()` protocol doors with `doc_id` targeting, streaming, honest usage accounting, and prompt-cache continuity across turns. Envelopes append verbatim: `messages()` output goes back into the next request unchanged.
- **Model & connection knobs**: `index_model` / `chat_model`, `index_backend` / `chat_backend` (and per-call `backend`) passed verbatim to each lane — LiteLLM-routed providers, keyless OpenAI-compatible servers, Azure/Bedrock/Vertex included.
- **`index=` / `chat=` slots**: the grouped spelling of the flat arguments — a string shorthand or a mapping (`index={"model": ..., "storage_path": ...}`, `chat={"model": ..., "backend": ...}`). `"cloud"` / `"local"` name a side, an optional `mode=` cross-checks it, and `PageIndexLocalClient` / `PageIndexCloudClient` take the same slots. `PageIndexCloudClient()` reads `PAGEINDEX_API_KEY`; a bare `PageIndexClient()` stays local no matter what the environment holds.
- **Typed config shapes**: `IndexConfig` / `CloudIndexConfig` / `LocalIndexConfig` / `ChatConfig`, with `py.typed` shipped so your type checker sees them.
- **Nothing fails quietly**: unknown keys, mixed sides, empty values and mode/content conflicts refuse at construction with the legal vocabulary in the message; dead credentials or a missing model fail the indexing run instead of storing a document with blank summaries; every cloud error carries its HTTP status.
- **Dependencies**: Python >= 3.10; `openai-agents` in the base install (the chat engine); `[anthropic]` and `[claude]` extras for those SDKs.

## Also in 0.2.13

- **Streamed `chat()` now shows the run.** Iterating `chat(stream=True)` weaves the process into the text by default — thinking, tool calls, and clipped results, then the answer. **This changes what a streamed `chat()` prints**: pass `show_process=False` for the bare answer stream, and when joining a stream back into conversation history. A dict (`pageindex.ChatProcessOptions`) selects the parts — `thinking` / `tool_calls` / `tool_results`, plus `max_chars` for the line cap.
- **`ChatStream.events`** — the same run as machine-readable typed dicts, full data, never clipped: `{"type": "thinking"|"answer", "delta": ...}`, `{"type": "tool_call", "call_id", "name", "arguments"}`, `{"type": "tool_result", "call_id", "name", "output"}`. Iterating the stream still yields text, so existing `for piece in client.chat(..., stream=True)` code keeps its shape; one run serves one view, and `close()` ends it like a closed generator. Non-stream `chat()` and the protocol doors are untouched.
- **Managed cloud streams show what the endpoint serves** — tool-call lines are parsed from the chunk tags the managed endpoint sends (that wire carries no thinking and no tool results). As a consequence the answer view no longer leaks the tool-argument JSON the endpoint interleaves into its content deltas.
- **litellm's terminal noise stays out of your answers** — the red `Provider List` banner it prints on every completion for models outside its static map is off, its WARNING chatter is gated to ERROR (an explicit `LITELLM_LOG` still wins), and the retry notice rides logging instead of stdout. Errors still raise with their full text, and importing pageindex leaves a host process's own litellm untouched.
- **Docs**: the README gains query-cost charts — against handing the model the whole PDF, native input costs 2.1x more at 52 pages and 16.6x more at 420 — and the usage guide moves to [docs.pageindex.ai](https://docs.pageindex.ai/getting-started).

**Full Changelog**: https://github.com/VectifyAI/PageIndex/compare/v0.2.12...v0.2.13