mirror of
https://github.com/turnstonelabs/turnstone.git
synced 2026-08-12 23:12:23 -06:00
9be155b97a
* Quality overhaul: code tooling, CI/CD, architecture diagrams, UI redesign, and legacy cleanup - Add ruff (lint+format) and mypy (strict) with zero errors across 37 source files - Add GitHub Actions CI (lint, typecheck, test matrix 3.11/3.12/3.13) and PyPI publish workflow - Create 12 PlantUML architecture diagrams with PNG renders covering all subsystems - Refresh README and docs with badges, diagram links, and current descriptions - Refactor test_server_live.py with mock streaming helpers for deterministic CI testing - Update dependencies to current versions (openai>=2.24, httpx>=0.28, redis>=7.2) Console dashboard: - Move state indicators from top cards to fixed bottom status bar with cluster metrics - Replace flat 50-node list with hostname-prefix grouped nodes (expand/collapse, up to 1000) - Apply "Instrument Panel" visual redesign: IBM Plex Mono + Outfit fonts, warm amber accent, LED glow state indicators, deep charcoal surfaces, WCAG AA contrast compliance - Add render cache, stale indicator, active filter highlight, loading states Server web UI: - Apply matching Instrument Panel aesthetic for visual consistency with console - Fix branding (pcode → turnstone), extract inline styles to CSS classes - Rename pcode localStorage keys and history state to turnstone Legacy cleanup: - Remove persona-model-specific --persona flag and /persona slash command - Remove model_identity from chat_template_kwargs (vLLM-specific mechanism) - Refactor plan agent to use standard developer message instead of model_identity - Remove dead code (unused date/has_tools variables, noqa suppressions) * Fix CI typecheck: add mypy overrides for optional sympy/numpy imports The math sandbox optionally imports sympy and numpy at runtime (try/except ImportError). In CI these packages are not installed, so mypy raises import-not-found rather than import-untyped. Add mypy overrides to ignore missing imports for these optional dependencies. * Fix Copilot review findings: ARIA role, status bar cache, and pulse opacity - Change #node-table from role="tree" to role="list" and group elements from role="treeitem" to role="listitem" (proper ARIA semantics) - Include currentView and currentFilter.state in renderStatusBar cache key so active pill highlight updates when switching views - Align pulse animation to 0.35 opacity (already applied in CSS)
82 lines
2.5 KiB
Plaintext
82 lines
2.5 KiB
Plaintext
@startuml
|
|
!theme plain
|
|
title Turnstone — Workstream State Machine
|
|
|
|
skinparam state {
|
|
BackgroundColor<<idle>> #E8F5E9
|
|
BackgroundColor<<thinking>> #E3F2FD
|
|
BackgroundColor<<running>> #FFF3E0
|
|
BackgroundColor<<attention>> #FCE4EC
|
|
BackgroundColor<<error>> #FFCDD2
|
|
}
|
|
|
|
state "IDLE" as idle <<idle>> : Waiting for user input.\nNo active LLM call or tool execution.
|
|
state "THINKING" as thinking <<thinking>> : LLM streaming response.\nTokens flowing (reasoning + content).
|
|
state "RUNNING" as running <<running>> : Tools executing.\nThreadPoolExecutor active.
|
|
state "ATTENTION" as attention <<attention>> : Blocked on user action.\nTool approval or plan review needed.
|
|
state "ERROR" as error <<error>> : Exception occurred.\nRecoverable on next send().
|
|
|
|
[*] --> idle : Session created
|
|
|
|
idle --> thinking : send() called\n_emit_state("thinking")
|
|
|
|
thinking --> running : Tool calls detected\nin LLM response\n_emit_state("running")
|
|
|
|
thinking --> idle : No tool calls\n(final answer)\n_emit_state("idle")
|
|
|
|
thinking --> error : Exception during\nstreaming
|
|
|
|
running --> attention : approve_tools() called\n_emit_state("attention")
|
|
|
|
attention --> running : User approves\n(tools execute)\n_emit_state("running")
|
|
|
|
attention --> running : User denies\n(denial recorded)\n_emit_state("running")
|
|
|
|
running --> thinking : Tool results appended,\nnext LLM call\n_emit_state("thinking")
|
|
|
|
running --> attention : Plan tool complete,\non_plan_review()\n_emit_state("attention")
|
|
|
|
running --> error : Exception during\ntool execution
|
|
|
|
error --> thinking : New send() call\n_emit_state("thinking")
|
|
|
|
note right of thinking
|
|
**Emitted via:**
|
|
session._emit_state(state)
|
|
→ ui.on_state_change(state)
|
|
|
|
**Propagation:**
|
|
• WebUI → global SSE queue (ws_state)
|
|
• Bridge → PUBLISH to global + cluster channels
|
|
• CLI → WorkstreamManager.set_state()
|
|
end note
|
|
|
|
note left of attention
|
|
**Blocking mechanisms:**
|
|
• TerminalUI: input() prompt
|
|
• WebUI: threading.Event.wait()
|
|
• Bridge: BLPOP on response queue
|
|
• NullUI: auto-approve (never reaches)
|
|
end note
|
|
|
|
state "SimWorkstream (simplified)" as sim_group {
|
|
state "sim_idle" as si <<idle>>
|
|
state "sim_thinking" as st <<thinking>>
|
|
state "sim_running" as sr <<running>>
|
|
state "sim_error" as se <<error>>
|
|
|
|
[*] --> si
|
|
si --> st : process_turn() called
|
|
st --> sr : Tool calls generated
|
|
sr --> st : More rounds
|
|
st --> si : No tools / max rounds
|
|
st --> se : Uncaught exception
|
|
}
|
|
|
|
note right of sim_group
|
|
SimWorkstream has no ATTENTION state —
|
|
tool approval is not simulated.
|
|
end note
|
|
|
|
@enduml
|