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…
How an agent operates inside a PyWry chat widget — reading user messages, attachments, @-context, tool-call result cards, edit/resend, settings changes.
$ npx -y skills add deeleeramone/PyWry --skill chat_agent --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/chat_agentContext preview
The summary Claude sees to decide when to auto-load this skill.
How an agent operates inside a PyWry chat widget — reading user messages, attachments, @-context, tool-call result cards, edit/resend, settings changes.
description: How an agent operates inside a PyWry chat widget — reading user messages, attachments, @-context, tool-call result cards, edit/resend, settings changes.
> **You are running INSIDE a PyWry chat widget.** This skill is not > about *creating* a chat — it's about operating correctly when the > chat is the UI you're attached to.
The user types a message; the chat manager packages it and passes it to your provider (`DeepagentProvider` or equivalent). You receive:
into a block prepended to the message
`session_id` / `thread_id` keyed checkpointer
Your reply is streamed token-by-token into the UI. Tool calls you make are shown as collapsible tool-result cards in the chat.
When the user types `@chart` (or any other registered context source), the chat manager prepends a block to the message like:
--- Attached: chart --- widget_id: chart <...any additional component context...> --- End Attached --- <the user's actual text>
The first line after the marker is ALWAYS `widget_id: <id>` for widget attachments. Read that value out and use it as the `widget_id` argument on every tool call for this turn. Never guess — the attachment is the source of truth.
If the user references a widget without attaching it, either:
1. Call `list_widgets()` to look it up by name. 2. Ask the user to attach it (`"Type @chart so I know which widget you mean."`).
Do NOT invent a widget_id.
Some examples register context sources that get auto-attached to every user message. In that case you'll see the `--- Attached ---` block even when the user didn't explicitly type `@<name>`. Treat it the same way — read `widget_id` and use it.
Every tool call you make is rendered in the chat as a card showing:
The user sees this UI. That means:
new symbol, saying "I called tvchart_symbol_search with query=MSFT and it returned MSFT" is noise — the card already shows it. Short confirmation ("Switched to MSFT.") is enough.
markdown like "Updated Chart State: { symbol: ..., lastUpdated: ... }" — the user will read it as if it came from a tool, and it didn't. Call the tool.
The chat panel has a settings menu. When the user changes a setting (model, temperature, etc.), your provider's `on_settings_change` callback fires. The provider may rebuild the underlying agent — the conversation history survives because it's keyed by thread_id in the checkpointer.
As the agent, you don't invoke settings changes yourself; the UI does. Just continue the conversation across the rebuild.
The user can click "Edit" on their own prior message to rewrite it, or "Resend" to re-fire a prior message with the current state. In either case the chat manager truncates the thread at that point and replays forward. You receive the (possibly edited) message as a fresh turn; prior assistant turns after that point are gone.
If the user's message asks for two or more distinct actions (e.g. "switch to MSFT and go weekly", "add a 50 SMA and a 200 SMA"), follow this flow:
1. Call `write_todos` with one entry per action, all in `pending` status. This renders as a plan card above the chat input.
2. For each step in order, issue BOTH tool calls in the SAME model response (parallel tool calls on one assistant message):
prior step kept `completed`, every remaining step kept `pending`.
Issuing them together halves the round-trips per step and keeps the plan card in sync with the actual work in real time. Do NOT split them across two turns.
3. After the last step's parallel `tool + write_todos` response has returned, reply with ONE sentence summarising the final state.
You MUST complete every step in the SAME turn. Do not stop after the first tool call. Do not emit a summary reply before every `pending` step is `completed`.
If a tool returns `confirmed: false` or an `error`, STOP THE PLAN. In the next response, call `write_todos` alone with the failed step marked `failed` and every remaining step kept `pending`, then reply with ONE sentence naming the failed step and the tool's `reason`. Do NOT run the remaining steps — they usually depend on the one that failed, and running them blind wastes tool calls and corrupts state.
Single-action requests skip `write_todos` entirely — one tool call, one reply sentence, done.
These rules are load-bearing. The chat UI already shows the tool-call cards, so prose that echoes the tool output is pure noise.
a compare series." "Switched to MSFT on the weekly." No section headers, no "Key Points", no "Likely Causes", no "Next Steps" preambles.
`tvchart_request_state(widget_id="chart")` in your reply is a hallucinated tool call — it does nothing. If you want to call a tool, invoke it.
ask one plain-English question. If a retry is obvious, retry — don't ask permission.
shows them. Saying "Wi
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.
**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.