view

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: Aug 25, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package view does result-shaping: the bookends+window anchored view, org-wide discovery (lineage-deduped, RRF-fused when an embedder is wired), scroll (keep-reading), and browse (no-query recent sessions).

Ordering within a session is by message id (insertion order), NOT ts — ts can be non-monotonic, so id is the reliable ordering key.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FilterDisplayable added in v0.9.0

func FilterDisplayable(msgs []store.Msg, want int, includeTools bool) []store.Msg

FilterDisplayable keeps the first want displayable records of msgs, in the order given. Callers that want the records nearest the END of a session pass them newest-first and reverse the result. With includeTools set nothing is dropped and this is a plain take-want.

func FilterDisplayableWith added in v0.9.0

func FilterDisplayableWith(msgs []store.Msg, want int, includeTools, includeThinking bool) []store.Msg

FilterDisplayableWith keeps the first want displayable records of msgs with granular tool and thinking inclusion.

func IsDisplayable added in v0.9.0

func IsDisplayable(content string) bool

IsDisplayable reports whether a record still says something after everything a runtime generated is removed. It is the display-side twin of the rule search already applies to its haystack, and it is the single place that rule lives for rendering: strip tool runs and injected envelopes, then reject what is left if it is empty, a bare block label (the ~99.5% redacted-thinking case), or the runtime's interruption note.

Nothing is deleted or hidden from the store by this — `--include-tools` puts every dropped row back, exactly as it does for search.

func IsDisplayableWith added in v0.9.0

func IsDisplayableWith(content string, includeTools, includeThinking bool) bool

IsDisplayableWith reports whether a record still says something according to the requested tool and thinking inclusions.

func IsInterruptionMarker added in v0.9.0

func IsInterruptionMarker(content string) bool

IsInterruptionMarker reports whether a record is the runtime's "the operator stopped me" note rather than anything either party said. It survives StripGenerated (it carries no tool marker and no envelope tag) but captioning a session with it says nothing about what that session is doing.

Measured across the live corpus by sampling the last three records of every session: 51 tails ended on this marker. [THINKING] (470) and [SYSTEM] (53) are deliberately NOT filtered here — reasoning that carries text is often the truest statement of what a session is working on right now, and a [SYSTEM] note is real injected content.

Corrected 2026-08-05: that reasoning holds only for blocks that carry text, and on this corpus almost none do — about 99.5% of thinking records are the bare label with an empty body (redacted reasoning). Those are skipped by isBareBlockMarker, which filters on emptiness rather than on block type, so the rule above is unchanged for any block that actually says something.

Exported alongside SessionLastActivity because every reader that walks a session tail looking for something a PERSON said has to step over it — including the one that finds where the caller's live turn began (agentproto.currentTurnStart).

func Reversed added in v0.9.0

func Reversed(msgs []store.Msg) []store.Msg

Reversed returns msgs in the opposite order.

func SessionLastActivity added in v0.9.0

func SessionLastActivity(con *sql.DB, sessionID string) string

SessionLastActivity returns the session's most recent REAL activity: the newest message that still has content once tool runs and injected envelopes are stripped (parse.StripGenerated). Walking newest-first and skipping generated rows is OpenClaw's selectBoundedActiveTailRecords in miniature.

Returns "" when the whole scanned tail is machinery — honest silence beats captioning a session with a tool result. The row still renders; it just has no "now" line, and Preview still says what the session was for.

Exported because a browse row is not the only place the question "and then what?" gets asked: a search hit is a point in the middle of a conversation, so the same tail read answers where that conversation ended up (agentproto.attachLastActivity). One definition of "real activity" for both, or the two surfaces drift.

func SessionPreview added in v0.9.0

func SessionPreview(con *sql.DB, sessionID string, cap int) string

SessionPreview returns the first SUBSTANTIVE user message's display text for a session — the ask that started it (low-signal openers like 'hi' or '/clear' are skipped via parse.IsSubstantive). The session is never dropped — if no early message is substantive, the first non-empty user message is shown as a fallback so the row still previews something.

browse renders it as the row preview; search uses it as the header-line title when a session was never tagged, which is most of them. Both want the same thing — "what was this about, in the user's own words" — so both read it here. cap is the caller's line budget: a browse row affords more width than a search header line that already carries a stamp, an id and a project.

Types

type AnchoredView

type AnchoredView struct {
	BookendStart   []ViewMsg `json:"bookend_start"`
	Window         []ViewMsg `json:"window"`
	BookendEnd     []ViewMsg `json:"bookend_end"`
	MessagesBefore int       `json:"messages_before"`
	MessagesAfter  int       `json:"messages_after"`
}

AnchoredView is the goal→match→resolution shape around one anchor message.

func BuildAnchoredView

func BuildAnchoredView(con *sql.DB, sessionID string, anchorID int, opts AnchoredViewOpts) *AnchoredView

BuildAnchoredView builds the ±window + bookends shape around anchorID in session. Returns nil if the window is empty. (Named BuildAnchoredView, not AnchoredView, to avoid colliding with the AnchoredView result type.)

type AnchoredViewOpts

type AnchoredViewOpts struct {
	Window          int
	Bookend         int
	IncludeTools    bool
	IncludeThinking bool
}

AnchoredViewOpts groups the optional tuning of AnchoredView (window radius, bookend size, tool inclusion) to keep the signature small. Defaults: Window=5, Bookend=3, IncludeTools=false.

type BrowseAllRow added in v0.5.0

type BrowseAllRow struct {
	Project string `json:"project"`
	BrowseRow
}

BrowseAllRow is one recent-session row of the cross-project (--all) browse: a BrowseRow tagged with the project it came from.

func BrowseScoped added in v0.10.0

func BrowseScoped(con *sql.DB, limit int, since, before, sourceTool string, projects []string) ([]BrowseAllRow, error)

BrowseScoped queries recent sessions from an open connection (draining rows first) and populates preview and last activity using the same connection.

type BrowseRow

type BrowseRow struct {
	SessionID string  `json:"session_id"`
	LastTS    float64 `json:"last_ts"`
	N         int     `json:"n"`
	Preview   string  `json:"preview"`
	Last      string  `json:"last,omitempty"`
}

BrowseRow is one recent-session row.

Preview and Last answer two different questions and neither substitutes for the other. Preview is the session's OPENING — what it was set up to do, which is its identity and stays true forever. Last is its most recent real activity — what it is doing NOW, which is the whole point of a recency-ordered list.

Keeping both is OpenClaw's split: its session store carries `firstUserMessage` and `lastMessagePreview` as separate fields and its session-list tool exposes them as `derivedTitle` and `lastMessagePreview` (src/gateway/session-utils.fs.ts, src/agents/tools/sessions-list-tool.ts). Showing only the opening — which is what this did, and what Hermes' `sessions list` still does — answers "what is this desk saying right now" with the prompt it was given a thousand messages ago.

func Browse

func Browse(tdir string, limit int, since, before string) []BrowseRow

Browse returns a project's most-recent top-level sessions (no query). since/before ("" = no bound) are local-date filters on last_ts.

func BrowseDB added in v0.5.0

func BrowseDB(dbp string, limit int, since, before string) []BrowseRow

BrowseDB is Browse over an already-resolved index db (a pre-ensured scope — Codex, retained/orphaned, or a Claude scope the caller resolved itself).

type Scope

type Scope struct {
	Project    string
	TDir       string // Claude transcript dir; "" for a pre-resolved (DBP) scope
	DBP        string // pre-ensured db path; "" means resolve lazily from TDir
	CWD        string // working dir for path filtering; "" means derive from TDir
	Source     string // "claude" | "codex"
	Origin     string // owning machine id for a replicated scope; "" = local
	OriginName string // owning machine display name; "" = local
	Stale      bool   // replica may lag its origin — report, still serve
}

Scope is one searchable unit discovery/scroll iterate over. A Claude scope is a (project label, transcript dir) pair whose db is resolved lazily from TDir. A non-directory source (e.g. Codex) instead sets DBP (a pre-ensured db) and CWD (for path filtering), leaving TDir empty. Source names the runtime ("claude"/"codex") for the --source filter and display. Resolve/CWD in the scopes package pick the right field, so consumers stay source-agnostic.

A scope replicated from ANOTHER machine (a transcript archive dir) also carries its origin: Origin is the owning machine's stable id (what its rows stamp as origin_machine) and OriginName its human-readable machine dir name. Both empty = a local scope. Stale marks a replica whose last sync is old — the search layer reports it through the stale-fallback posture while still serving its results.

type ViewMsg

type ViewMsg struct {
	ID     int    `json:"id"`
	Role   string `json:"role"`
	Text   string `json:"text"`
	Anchor bool   `json:"anchor,omitempty"`
}

ViewMsg is one message in a window or bookend. The Anchor field is true only for the window's anchor message.

func RenderMsgs added in v0.9.0

func RenderMsgs(msgs []store.Msg, includeTools bool, cap int) []ViewMsg

RenderMsgs renders store rows for display at the given cap.

func RenderMsgsWith added in v0.9.0

func RenderMsgsWith(msgs []store.Msg, includeTools, includeThinking bool, cap int) []ViewMsg

RenderMsgsWith renders store rows for display with granular tool/thinking inclusion.

func TakeDisplayable added in v0.9.0

func TakeDisplayable(msgs []store.Msg, want int, includeTools bool, cap int) []ViewMsg

TakeDisplayable renders the FIRST want displayable records of msgs.

func TakeDisplayableTail added in v0.9.0

func TakeDisplayableTail(msgs []store.Msg, want int, includeTools bool, cap int) []ViewMsg

TakeDisplayableTail renders the LAST want displayable records of msgs, still in chronological order. Used for a closing bookend, where the interesting records are the ones nearest the end.

func TakeDisplayableTailWith added in v0.9.0

func TakeDisplayableTailWith(msgs []store.Msg, want int, includeTools, includeThinking bool, cap int) []ViewMsg

TakeDisplayableTailWith renders the LAST want displayable records with granular inclusions.

func TakeDisplayableWith added in v0.9.0

func TakeDisplayableWith(msgs []store.Msg, want int, includeTools, includeThinking bool, cap int) []ViewMsg

TakeDisplayableWith renders the FIRST want displayable records with granular inclusions.

Jump to

Keyboard shortcuts

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