httpsrv

package
v0.44.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 27, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package httpsrv wires Poe HTTP requests into the router.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DebugHandler

func DebugHandler(r *router.Router) http.Handler

DebugHandler returns an http.Handler that dumps router state as JSON.

Types

type CommandHandler added in v0.18.0

type CommandHandler interface {
	HasPending(convID string) bool
	Handle(ctx context.Context, convID, text string) (*command.Outcome, error)
	// Passthrough reports whether text is an allowlisted agent command;
	// if ok, rewritten is the prompt text to forward to the agent.
	Passthrough(text string) (rewritten string, ok bool)
}

CommandHandler is the surface httpsrv depends on; *command.Broker implements it. Extracted so tests can inject handlers that return odd combinations the real one can't produce.

type Config

type Config struct {
	Router *router.Router
	// Settings is the static response for `settings` requests. Parameter
	// controls may be overridden per-request by ParameterControlsProvider.
	Settings poeproto.SettingsResponse
	// HeartbeatInterval is the SSE heartbeat tick. The heartbeat
	// emits an animated `> _Thinking._` spinner via replace_response
	// until the first user-visible write closes the gate. <=0 disables
	// the heartbeat. Doubles as the spinner animation rate, so values
	// in the 1–2s range read well to humans.
	HeartbeatInterval time.Duration
	// ParameterControlsProvider, if set, is called on each `settings`
	// request to populate SettingsResponse.ParameterControls. If nil,
	// Settings.ParameterControls is used as-is.
	ParameterControlsProvider func() *poeproto.ParameterControls
	// Commands, if set, intercepts relay chat-commands (login family,
	// !help, !status, !models, !model, !new — any of the sigils /, !, .)
	// and pasted redirect URLs from in-flight logins before they reach
	// the router. Optional; nil disables the command surface.
	Commands CommandHandler
	// TurnTimeout is an OPTIONAL absolute wall-clock ceiling on a prompt
	// turn run on a context DECOUPLED from the request ctx. Poe tears
	// down the bot-facing HTTP connection pre-output on a transport drop;
	// decoupling lets the in-flight turn finish so its answer can be
	// buffered and served on the redrive, instead of aborting and losing
	// the work.
	//
	// <=0 (the default) means NO absolute ceiling: a turn is bounded
	// SOLELY by the progress-resetting IdleWriteTimeout backstop. While
	// the agent keeps producing user-visible output the turn runs for as
	// long as it needs — a long, actively-working turn is never cut. The
	// absolute cap is opt-in for operators who deliberately want a hard
	// upper bound regardless of progress; it is NOT a wedge guard (that
	// is IdleWriteTimeout's job).
	TurnTimeout time.Duration
	// AnswerTTL bounds how long a buffered (absorbed) turn answer is held
	// for a redrive before it is discarded. <=0 falls back to
	// defaultAnswerTTL (2m).
	AnswerTTL time.Duration
	// IdleWriteTimeout is the per-stream backstop for a WEDGED turn: the
	// agent has hung, no SSE content byte has been written, and the
	// client never disconnected. If no user-visible chunk lands within
	// this window the single wedged turn is cancelled so it cannot block
	// a graceful drain forever; every other in-flight stream keeps
	// draining. Heartbeat keepalive frames do NOT reset it — only real
	// agent output does — so a genuinely wedged turn is detected even
	// though its spinner keeps ticking. A tool_call session/update DOES
	// reset it: a legitimately long-running tool is genuine progress, so
	// it must not be cut. <=0 falls back to defaultIdleWriteTimeout (2m).
	IdleWriteTimeout time.Duration
	// StallThreshold is how long the SSE stream may go without a
	// user-visible content write before the heartbeat re-arms the
	// mid-turn keepalive spinner. Poe drops the bot-facing connection on
	// content-starvation, so during a long tool-heavy turn (no tokens
	// for minutes) the spinner must resume to keep the stream alive.
	// It re-arms via `replace_response` (a content event that renders in
	// place), preserving the text so far and animating a transient
	// status line below it; the moment real output resumes the spinner
	// is stripped. Before the first output there is no stall gate — the
	// cold-start spinner fires immediately (see heartbeat). <=0 falls
	// back to defaultStallThreshold (8s), conservatively under Poe's
	// drop tolerance. Reuses HeartbeatInterval for the animation cadence.
	StallThreshold time.Duration
	// SSEWriteTimeout bounds every SSE wire write via a per-write
	// connection deadline. A client that has stopped reading (Poe pressed
	// Stop, or a dead transport) applies TCP backpressure; without a
	// deadline a blocked write — including the terminal `done` — never
	// returns and the turn never finalizes (the "Stop button stays"
	// hang). With it, a wedged write fails after this window, the
	// heartbeat swallows the error, and the terminal `done` still seals
	// the stream so the HTTP response closes. <=0 falls back to
	// defaultSSEWriteTimeout (30s): generous enough never to cut a
	// slow-but-live reader mid-frame, tight enough to bound finalization.
	SSEWriteTimeout time.Duration
}

Config configures a Handler.

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler serves the /poe endpoint.

func New

func New(cfg Config) *Handler

New creates a Handler. HeartbeatInterval <=0 disables heartbeat; otherwise no defaulting is applied — pass an explicit value. AnswerTTL and IdleWriteTimeout default when <=0 (see their docs). TurnTimeout is NOT defaulted: <=0 means no absolute turn ceiling, so the progress-resetting IdleWriteTimeout backstop is the sole guard.

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL