pywry-orientation
When to reach for PyWry MCP tools (native webview rendering, Plotly, TradingView, AgGrid, chat) instead of writing Flask/Streamlit/Dash/Electron code. Use at…
**Read this before creating chat widgets.**
$ npx -y skills add deeleeramone/PyWry --skill chat --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/chatContext preview
The summary Claude sees to decide when to auto-load this skill.
**Read this before creating chat widgets.**
> **Read this before creating chat widgets.**
The chat component provides a full-featured conversational UI with:
{
"name": "create_chat_widget",
"arguments": {
"title": "AI Assistant",
"model": "gpt-4",
"system_prompt": "You are a helpful assistant.",
"streaming": true,
"provider": "openai"
}
}from pywry import App
from pywry.chat import ChatConfig, ChatWidgetConfig
app = App()
config = ChatWidgetConfig(
title="AI Chat",
height=600,
chat=ChatConfig(
system_prompt="You are helpful.",
model="gpt-4",
streaming=True,
provider="openai",
),
)
# Widget creation handled by MCP or directly via app.show()---
Creates a chat widget. Returns `{widget_id, thread_id}`.
| Parameter | Type | Default | Description | |----------------|---------|----------|--------------------------------| | title | string | "Chat" | Window title | | height | integer | 600 | Window height | | system_prompt | string | "" | System prompt for LLM | | model | string | "gpt-4" | Model name | | temperature | number | 0.7 | Sampling temperature (0-2) | | max_tokens | integer | 4096 | Max tokens per response | | streaming | boolean | true | Enable streaming | | persist | boolean | false | Persist threads in ChatStore | | provider | string | — | "openai", "anthropic", "callback" | | show_sidebar | boolean | true | Show thread sidebar | | slash_commands | array | — | Custom slash commands |
Send a user message. Returns `{message_id, thread_id, sent}`.
Stop an in-flight generation. Idempotent. Returns partial content.
Thread CRUD: create, switch, delete, rename, list.
Register a slash command at runtime.
Paginated conversation history with cursor (`before_id`).
Update model, temperature, system prompt, etc.
Show/hide the typing indicator.
---
| Event | Payload | |---------------------------|--------------------------------------------| | `chat:assistant-message` | `{messageId, text, threadId}` | | `chat:stream-chunk` | `{chunk, messageId, threadId, done}` | | `chat:typing-indicator` | `{typing, threadId}` | | `chat:switch-thread` | `{threadId}` | | `chat:update-thread-list` | `{threads: [{thread_id, title}]}` | | `chat:clear` | `{}` | | `chat:register-command` | `{name, description}` | | `chat:update-settings` | `{model, temperature, system_prompt}` | | `chat:state-response` | `{messages, threads, settings, activeThreadId}` | | `chat:generation-stopped` | `{messageId, threadId, partialContent}` |
| Event | Payload | |--------------------------|---------------------------------------------| | `chat:user-message` | `{text, threadId, timestamp}` | | `chat:slash-command` | `{command, args, threadId}` | | `chat:thread-create` | `{title}` | | `chat:thread-switch` | `{threadId}` | | `chat:thread-delete` | `{threadId}` | | `chat:settings-change` | `{key, value}` | | `chat:request-history` | `{threadId, limit}` | | `chat:stop-generation` | `{threadId, messageId}` | | `chat:request-state` | `{}` |
---
1. User clicks Stop button → frontend immediately re-enables UI 2. `chat:stop-generation` sent to backend 3. Backend sets `cancel_event` on `GenerationHandle` 4. LLM provider checks `cancel_event.is_set()` between chunks 5. Provider raises `GenerationCancelledError` → partial content saved 6. Backend emits `chat:generation-stopped` with partial content 7. Frontend marks message as "(stopped)"
The UI **never waits** for backend confirmation — recovery is instant.
---
| Command | Description | |-----------|----------------------------| | `/clear` | Clear conversation | | `/export` | Export chat history | | `/model` | Switch model | | `/system` | Change system prompt |
Register custom commands via `chat_register_command` tool or `ChatConfig.slash_commands` list.
---
{"provider": "openai"}Requires `openai` package and `OPENAI_API_KEY` environment variable.
{"provider": "anthropic"}Requires `anthropic` package and `ANTHROPIC_API_KEY` environment variable.
from pywry.chat.providers.callback import CallbackProvider
provider = CallbackProvider(
prompt_fn=my_prompt, # (session_id, content_blocks, cancel_event) → AsyncIterator[SessionUpdate]
)---
PyWry is a cross-platform app factory, rendering engine and UI toolkit for Python that produces native desktop, web, and notebook experiences from a single API.
Repo: deeleeramone/PyWry
When to reach for PyWry MCP tools (native webview rendering, Plotly, TradingView, AgGrid, chat) instead of writing Flask/Streamlit/Dash/Electron code. Use at…
Add OAuth2 authentication to PyWry apps — Google, GitHub, Microsoft, or any OIDC provider.
Autonomous PyWry application building using LLM sampling, elicitation, and progress reporting.
How an agent operates inside a PyWry chat widget — reading user messages, attachments, @-context, tool-call result cards, edit/resend, settings changes.
**STOP. THIS IS THE AUTHORITATIVE REFERENCE FOR ALL COMPONENTS.** **YOU MUST USE THE EXACT EVENT SIGNATURES DOCUMENTED HERE.** **THERE ARE NO EXCEPTIONS. NO…
Target elements for `set_content` and `set_style` updates using CSS selectors or component IDs.