-
Notifications
You must be signed in to change notification settings - Fork 1
Home
Detailed reference for the framework. The repo's
README.md covers the
quick start; everything deeper lives here.
Two complementary goals:
-
Exercise Spinel against real-world Ruby code. Tep is the largest pure-Ruby app Spinel compiles end-to-end. Every Sinatra idiom, every battery, every demo doubles as a torture test for the AOT compiler's codegen + analyzer. Bugs surface here, get reduced to minimal repros, and land upstream as PRs or issues.
-
Be the harness for toy. Toy is Tep's sibling project: a machine-learning framework written in pure Ruby and compiled by Spinel. Toy needs an HTTP / MCP / streaming layer for serving models, exposing training tools to agents (Claude Code et al.), streaming inference results, and wiring presence into collaborative training sessions. Tep is that layer. Every battery here is shaped by what Toy actually needs to ship.
Tep happens to be useful as a general web framework too — fast, single-binary, Sinatra-shaped — but the design choices flow from those two lenses.
- Getting Started — install, build, serve, and deploy your first Tep app, all the way through auth, persistence, and a systemd unit.
Pure-Tep modules covering the gem ecosystem's most common needs in a way that lowers cleanly through Spinel.
-
Tep::SQLite — libsqlite3 wrapper: prepare / bind /
step / col, plus
first_str/first_intconveniences. - Tep::Json — primitive encoders, flat-key decoder, hash/array helpers for JSON-over-HTTP.
- Tep::Logger — levelled logger; stderr or file.
-
Tep::Jwt — HS256 JWT encode / verify / decode; interop-
tested against the canonical
jwtgem. - Tep::Password — PBKDF2-SHA256 hashing with self- describing storage; 200k iters.
-
Tep::Security —
Cors(before-filter) +Headers(HSTS, nosniff, frame-options, ...). -
Tep::Assets — compile-time bundling for
<app>/assets/*(CSS, SVG, JS, ...). - Tep::Scheduler — cooperative fiber scheduler with timer + I/O parking.
-
Tep::Shell — popen-based shell-out + small-file reader
for
/proc,/sys,/etc. - Tep::Http — outbound HTTP/1.0 client, Faraday-shaped.
-
Tep::Llm — ruby-openai-shaped chat-completions client;
sync
chat+ SSEchat_stream. Backends interchangeable viabase_url(Ollama / OpenAI / toy). -
Tep::WebSocket — RFC 6455 server-side WebSocket.
Sinatra-style
websocket '/p' do |ws| ... endDSL withon_open/on_message/on_closeevent blocks. - Tep::Parallel — grosser/parallel-shaped fork fan-out.
- Tep::Job — sidekiq-shaped queue over SQLite.
These four ship a small framework for "web apps in a live
agentic age" — req.identity is always a principal+delegate
pair so agents acting on behalf of humans are first-class
through every battery. End-to-end design + a realistic chat-room
scenario walked through every seam lives in
docs/BATTERIES-DESIGN.md.
-
Tep::Auth — principal+delegate identity (humans +
agents) + provider chain: BearerToken (JWT), SessionCookie,
OAuth2-grant issuance. Same
req.identitysurface regardless of provider. -
Tep::Broadcast — in-process pub/sub + cross-
worker via PG LISTEN/NOTIFY. WS-framed
subscribe_wsis the seam Presence + LiveView use. -
Tep::Presence — topic-keyed who's-here
registry, agent-aware. Structured 3-state status (
:available | :busy | :blocked) with notes + expiry. Diffs broadcast on join/leave/status; PG mirror for cross-workerlist_globalsnapshots. -
Tep::LiveView — Phoenix.LiveView-shape
server-rendered stateful UI over WebSocket. Subclass +
override
render/handle_event; bootstrap client ships inline (~10 lines of JS). -
Tep::MCP — Tools + resources exposed via
Model Context Protocol
so Claude Code / OpenCode / Gravity CLI drive the app
natively. One DSL (
mcp_tool/mcp_resource) → JSON-RPC dispatcher at/mcp+ HTTP-direct routes + auto-published/llms.txt+/openapi.json.AGENTS.mdconvention for the prose-level invariants.
-
examples/counter/— the smallestTep.livedemo. Shared integer counter; click in one tab, every other tab updates in <100ms. ~80 lines. -
examples/experiments/— theTep::MCPbattery demo. Mock training-run manager driven by an MCP client: 4 tools, 2 resources, capability gating, auto-published catalog. ~200 lines + a workedAGENTS.md. -
examples/agentic_chat/— the four-battery agentic demo (~270 lines). Sub-second WS push, multi-user chat, agent-spawn with OAuth2-style delegation. Walks through Auth + Broadcast + Presence + LiveView end-to-end. -
examples/chatbot/— OpenWebUI-style client (~1500 lines) against any OpenAI- compatible endpoint, exercising the full pre-agentic battery surface. -
examples/websocket_echo.rb—Tep::WebSocketin isolation; the smallest possible WS app.
- Sinatra compatibility matrix — which Sinatra idioms translate (and which don't).
-
Examples directory —
smaller apps:
hello,sinatra_style,blog,chat.
Tep deliberately tracks Spinel's edges. If you hit something that "should work" — a Sinatra idiom that doesn't translate, a Spinel- emitted miscompile, a runtime hang — file an issue with a minimal reproduction at OriPekelman/tep/issues.