v0.3.80 f3f644f

lifecycle.go RawHistoryFolder

1package agent
2
3import (
4	"context"
5	"encoding/base64"
6	"unicode/utf8"
7
8	"github.com/patriceckhart/zot/packages/agent/extensions"
9	"github.com/patriceckhart/zot/packages/agent/extproto"
10	"github.com/patriceckhart/zot/packages/agent/swarm"
11	"github.com/patriceckhart/zot/packages/core"
12	"github.com/patriceckhart/zot/packages/provider"
13)
14
15func startExtensionSession(mgr *extensions.Manager, ag *core.Agent, cwd, reason string) {
16	id := ""
17	if ag != nil {
18		id = ag.SessionID
19	}
20	mgr.StartSession(id, cwd, reason)
21}
22
23func wireLifecycleEvents(ag *core.Agent, mgr *extensions.Manager) {
24	ag.OnEvent = func(ev core.AgentEvent) {
25		_, cwd := mgr.SessionContext()
26		startExtensionSession(mgr, ag, cwd, "session_switch")
27		fanoutAgentEvent(mgr, ev)
28	}
29}
30
31// Bound observation payloads independently from tool output and transcripts.
32// The budget includes base64 bytes; images are omitted rather than corrupted.
33const eventResultBudget = 256 * 1024
34
35func extensionEventResult(result core.ToolResult) *extproto.EventResult {
36	out := &extproto.EventResult{IsError: result.IsError, Content: []extproto.ContentBlock{}}
37	remaining := eventResultBudget
38	for _, block := range result.Content {
39		if len(out.Content) >= 128 {
40			out.Truncated = true
41			break
42		}
43		switch b := block.(type) {
44		case provider.TextBlock:
45			text := b.Text
46			if len(text) > remaining {
47				end := remaining
48				for end > 0 && !utf8.RuneStart(text[end]) {
49					end--
50				}
51				text = text[:end]
52				out.Truncated = true
53			}
54			remaining -= len(text)
55			out.Content = append(out.Content, extproto.ContentBlock{Type: "text", Text: text})
56		case provider.ImageBlock:
57			size := base64.StdEncoding.EncodedLen(len(b.Data)) + len(b.MimeType)
58			if size > remaining {
59				out.Truncated = true
60				continue
61			}
62			remaining -= size
63			out.Content = append(out.Content, extproto.ContentBlock{Type: "image", MimeType: b.MimeType, Data: base64.StdEncoding.EncodeToString(b.Data)})
64		default:
65			out.Truncated = true
66		}
67	}
68	return out
69}
70
71func emitPermissionDecision(ctx context.Context, mgr *extensions.Manager, call provider.ToolCallBlock, d core.ConfirmDecision) {
72	decision := "denied"
73	if d.Allow {
74		decision = "approved"
75	}
76	if ctx.Err() != nil {
77		decision = "cancelled"
78	}
79	mgr.EmitEvent(extproto.EventFromHost{Event: "permission_decision", ToolID: call.ID, ToolName: call.Name, Decision: decision, Source: d.Source, Reason: d.Reason, Stage: "pre_execution"})
80}
81
82func emitSwarmLifecycle(mgr *extensions.Manager, e swarm.LifecycleEvent) {
83	mgr.EmitEvent(extproto.EventFromHost{Event: e.Event, SessionID: e.SessionID, AgentID: e.AgentID, AgentRunID: e.AgentRunID, Name: e.Name, CWD: e.CWD, Status: e.Status, Error: e.Error})
84}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 476

↑↓ moveenter openesc close