Receber por email
← Voltar para o catálogo

PyWry

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.

90estrelas
Atualizado há 4 meses

Ver no GitHub ↗ Licença: Apache-2.0

Como adicionar

/plugin marketplace add deeleeramone/PyWry

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/pywry-mpstbprj/svg)](https://www.skillteca.com.br/skills/pywry-mpstbprj)

Alerta por categoria

Receba novas skills de Design e Frontend toda segunda

1 email curto, só com as skills novas de Design e Frontend. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Chat Component - Reference Guide

Read this before creating chat widgets.

Overview

The chat component provides a full-featured conversational UI with:

  • Message rendering with inline markdown
  • Streaming responses with token-by-token display
  • Stop-generation (cancel in-flight LLM responses)
  • Thread management (create, switch, delete)
  • Slash command palette (type / to see commands)
  • Settings panel (model, temperature, system prompt)
  • LLM provider adapters (OpenAI, Anthropic, custom callback)

Quick Start

Via MCP Tool

{
  "name": "create_chat_widget",
  "arguments": {
    "title": "AI Assistant",
    "model": "gpt-4",
    "system_prompt": "You are a helpful assistant.",
    "streaming": true,
    "provider": "openai"
  }
}

Via Python

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()

MCP Tools

create_chat_widget

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 |

chat_send_message

Send a user message. Returns {message_id, thread_id, sent}.

chat_stop_generation

Stop an in-flight generation. Idempotent. Returns partial content.

chat_manage_thread

Thread CRUD: create, switch, delete, rename, list.

chat_register_command

Register a slash command at runtime.

chat_get_history

Paginated conversation history with cursor (before_id).

chat_update_settings

Update model, temperature, system prompt, etc.

chat_set_typing

Show/hide the typing indicator.

Event Contract

Incoming Events (Python → Frontend)

| 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} |

Outgoing Events (Frontend → Python)

| 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 | {} |

Stop-Generation Mechanics

  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.

Default Slash Commands

| 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.

LLM Providers

OpenAI

{"provider": "openai"}

Requires openai package and OPENAI_API_KEY environment variable.

Anthropic

{"provider": "anthropic"}

Requires anthropic package and ANTHROPIC_API_KEY environment variable.

Custom Callback

from pywry.chat.providers.callback import CallbackProvider

provider = CallbackProvider(
    prompt_fn=my_prompt,   # (session_id, content_blocks, cancel_event) → AsyncIterator[SessionUpdate]
)

Safety Constants

| Constant | Value | Purpose | |--------------------------|----------|----------------------------------| | MAX_RENDERED_MESSAGES | 200 | DOM cap for performance | | MAX_CONTENT_LENGTH | 100,000 | Per-message content limit | | MAX_MESSAGES_PER_THREAD | 1,000 | Eviction threshold | | STREAM_TIMEOUT_SECONDS | 30 | Max silence before timeout | | SEND_COOLDOWN_MS | 1,000 | Input rate limit | | GENERATION_HANDLE_TTL | 300 | Auto-expire stale handles |

Compartilhar X LinkedIn