Chat Artifacts And Providers¶
PyWry chat handlers can emit more than plain text. ChatManager supports structured response objects for status updates, citations, tool call traces, thinking output, todo tracking, user input requests, and rich artifacts.
This page covers the advanced capabilities of the chat system, detailing how to render rich artifacts and integrate with various AI providers.
Installation¶
The chat UI itself ships with the base package. Provider-backed integrations map directly to the adapter classes in pywry.chat_providers:
pip install 'pywry[openai]'forOpenAIProviderpip install 'pywry[anthropic]'forAnthropicProviderpip install 'pywry[magentic]'forMagenticProviderpip install 'pywry[all]'for all optional integrations together
Rich Chat Responses¶
Handlers may yield ChatResponse objects mixed with plain text chunks. Common response types include:
StatusResponsefor transient inline status messagesThinkingResponsefor collapsible reasoning outputTodoUpdateResponsefor task list stateToolCallResponseandToolResultResponsefor agent/tool tracesCitationResponsefor source referencesInputRequiredResponsefor interactive pauses
These can be mixed freely with regular text streaming.
from pywry import StatusResponse, ThinkingResponse, ToolCallResponse, ToolResultResponse
def handler(messages, ctx):
query = messages[-1]["text"]
yield StatusResponse(text="Searching documentation...")
yield ThinkingResponse(text="Selecting the most relevant modules first.\n")
yield ToolCallResponse(name="search_docs", arguments={"query": query})
yield ToolResultResponse(tool_id="call_123", result="Found 3 relevant modules")
yield "Here is the synthesized answer."
Artifact Types¶
Artifacts render as standalone blocks in the chat transcript and are not treated as token-by-token message content.
CodeArtifact¶
Displays syntax-highlighted code.
from pywry import CodeArtifact
yield CodeArtifact(
title="main.py",
language="python",
content="print('hello from PyWry')",
)
MarkdownArtifact¶
Renders Markdown as formatted content.
from pywry import MarkdownArtifact
yield MarkdownArtifact(
title="Summary",
content="# Results\n\n- Build passed\n- 12 tests green",
)
HtmlArtifact¶
Embeds raw HTML in a sandboxed container.
from pywry import HtmlArtifact
yield HtmlArtifact(
title="Status Card",
content="<div style='padding:12px'><strong>Healthy</strong></div>",
)
TableArtifact¶
Renders interactive AG Grid content inside the chat transcript. It accepts the same data shapes as normalize_data() in pywry.grid.
from pywry import TableArtifact
yield TableArtifact(
title="Positions",
data=[
{"symbol": "AAPL", "qty": 120, "price": 189.84},
{"symbol": "MSFT", "qty": 80, "price": 425.22},
],
height="320px",
)
PlotlyArtifact¶
Embeds an interactive Plotly figure.
from pywry import PlotlyArtifact
yield PlotlyArtifact(
title="Revenue",
figure={
"data": [{"type": "scatter", "x": [1, 2, 3], "y": [3, 5, 8]}],
"layout": {"title": {"text": "Revenue Trend"}},
"config": {"responsive": True},
},
height="360px",
)
ImageArtifact¶
Displays an image using an HTTP(S) URL or a data URI.
from pywry import ImageArtifact
yield ImageArtifact(
title="Diagram",
url="https://example.com/diagram.png",
alt="Architecture diagram",
)
JsonArtifact¶
Displays structured JSON in a collapsible viewer.
from pywry import JsonArtifact
yield JsonArtifact(
title="API Response",
data={"status": 200, "ok": True, "items": [1, 2, 3]},
)
Asset Loading For Artifacts¶
TableArtifact and PlotlyArtifact need frontend libraries. ChatManager supports two strategies:
- Set
include_aggrid=Trueandinclude_plotly=Truein the constructor to preload those libraries. - Leave them off and let the manager inject them lazily the first time the corresponding artifact type is emitted.
If you know the assistant will definitely emit tables or charts, eager loading avoids the first-render delay.
Provider Layer¶
The lower-level provider system in pywry.chat_providers adapts external LLM clients to PyWry chat models.
Available providers:
OpenAIProviderAnthropicProviderCallbackProviderMagenticProviderget_provider(name, **kwargs)factory
These providers operate on ChatMessage lists plus a ChatConfig object and return either a full ChatMessage or a stream of chunks.
CallbackProvider¶
CallbackProvider is the lightest integration point if you already have your own Python callables and want a provider-shaped adapter.
from pywry.chat import ChatConfig, ChatMessage
from pywry.chat_providers import CallbackProvider
def generate_fn(messages, config):
return "Complete response"
def stream_fn(messages, config, cancel_event):
for chunk in ["streamed ", "response"]:
if cancel_event and cancel_event.is_set():
return
yield chunk
provider = CallbackProvider(generate_fn=generate_fn, stream_fn=stream_fn)
OpenAI And Anthropic Providers¶
The OpenAI and Anthropic adapters lazily import their optional dependencies.
from pywry.chat_providers import OpenAIProvider, AnthropicProvider
openai_provider = OpenAIProvider(api_key="...")
anthropic_provider = AnthropicProvider(api_key="...")
Both support:
- Full-message generation via
generate(...) - Streaming via
stream(...) ChatConfiginputs for model, temperature, token limit, and system prompt- Cooperative cancellation through
cancel_event
MagenticProvider¶
MagenticProvider wraps magentic ChatModel backends and gives you access to OpenAI-compatible providers, Anthropic, LiteLLM-backed models, and other magentic-supported engines through one adapter.
from pywry.chat_providers import MagenticProvider
provider = MagenticProvider("gpt-4o-mini", api_key="...")
You can also pass a preconfigured magentic ChatModel instance directly.
Provider Factory¶
Use get_provider() when you want a name-based configuration path.
Supported names are openai, anthropic, callback, and magentic.
Low-Level Chat Models¶
The provider layer uses these core types from pywry.chat:
ChatMessageChatThreadChatConfigChatWidgetConfigGenerationHandleGenerationCancelledError
Use these directly if you are building a custom orchestration layer instead of ChatManager.
Example Files¶
pywry/examples/pywry_demo_chat_artifacts.pyshows all seven artifact types.pywry/examples/pywry_demo_chat.pyshows status, thinking, todo, slash commands, and input-required flows.