Documentation
¶
Overview ¶
Package oriagent is an application shell for agent clients, in the style of the Claude Code desktop "work" view: custom title bar, sidebar tree of projects → sessions → subagents, chat transcript with streamed reasoning, tool calls and task lists, composer with slash-command palette, voice dictation and attachments, resizable document preview, Pomodoro timer, setup and profile pages. Colors follow the Ori design system.
A project plugs its own behavior through Config: an Agent that writes each turn, extra slash Commands, extra Pages, models, user, demo data.
oriagent.Run(oriagent.Config{
AppName: "Mon assistant",
Agent: myAgent,
})
It runs on Windows, macOS and Linux without CGO on Windows; macOS and Linux need the usual Gio toolchain.
Index ¶
- Constants
- Variables
- func HumanSize(n int64, tr i18n.Translator) string
- func NewSessionID() string
- func Run(cfg Config)
- type Agent
- type AgentFunc
- type App
- type ApprovalRequest
- type Attachment
- type Block
- type C
- type Command
- type Config
- type Ctl
- func (c *Ctl) Clear()
- func (c *Ctl) Commands() []*Command
- func (c *Ctl) Dark() bool
- func (c *Ctl) LanguageName(locale string) string
- func (c *Ctl) Locale() string
- func (c *Ctl) Locales() []string
- func (c *Ctl) Model() int
- func (c *Ctl) Models() []Model
- func (c *Ctl) NewSession()
- func (c *Ctl) NewSessionIn(p *Project)
- func (c *Ctl) Notify(msg string)
- func (c *Ctl) Open(path string) error
- func (c *Ctl) PickFiles()
- func (c *Ctl) Pomodoro() *Pomodoro
- func (c *Ctl) Projects() []*Project
- func (c *Ctl) RunTurn(prompt string, fn TurnFunc) error
- func (c *Ctl) Session() *Session
- func (c *Ctl) Sessions() []*Session
- func (c *Ctl) SetDark(dark bool)
- func (c *Ctl) SetLocale(locale string) error
- func (c *Ctl) SetModel(i int)
- func (c *Ctl) SetModels(ms []Model)
- func (c *Ctl) SetUser(u User)
- func (c *Ctl) Settings() Settings
- func (c *Ctl) Show(view string)
- func (c *Ctl) T(key string, args ...any) string
- func (c *Ctl) ToggleSidebar()
- func (c *Ctl) ToggleVoice()
- func (c *Ctl) User() User
- func (c *Ctl) WorkDir() string
- type D
- type Decision
- type Device
- type Dictation
- type Features
- type Headless
- type HistoryEntry
- type Kind
- type Leveler
- type LocaleSetter
- type Message
- type Model
- type Page
- type Permissions
- type Pomodoro
- type PomodoroConfig
- type ProfileLock
- type Project
- type ProjectEdit
- type ProjectFile
- type Session
- type Settings
- type SimDictation
- type Task
- type TaskList
- type TaskStatus
- type ToolCall
- type Turn
- func (t *Turn) Approve(ctx context.Context, req ApprovalRequest) (Decision, error)
- func (t *Turn) Finish(report string)
- func (t *Turn) Notify(msg string)
- func (t *Turn) SetModels(ms []Model)
- func (t *Turn) SetUser(u User)
- func (t *Turn) Subagent(title, prompt string) *Turn
- func (t *Turn) T(key string, args ...any) string
- func (t *Turn) Tasks(items ...string) *TaskList
- func (t *Turn) Text() *Block
- func (t *Turn) Think() *Block
- func (t *Turn) Tool(name, arg string) *ToolCall
- type TurnFunc
- type TurnOptions
- type User
Examples ¶
Constants ¶
const MaxUpload = 20 << 20
MaxUpload is the size limit for attachments.
Variables ¶
var Catalogs = map[string]map[string]string{"fr": catalogFR, "en": catalogEN}
Catalogs holds the built-in interface strings, by locale then key. To add a language, give Config.Translations a catalog with the same keys ("lang.name" is the language's own name, shown in the language picker); missing keys fall back to Config.FallbackLocale.
var ErrSessionBusy = errors.New("oriagent: a turn is already running in this session")
ErrSessionBusy is returned by Headless.Run when a turn is already running in the session.
Functions ¶
func HumanSize ¶
func HumanSize(n int64, tr i18n.Translator) string
HumanSize formats a byte count in the language of tr ("1,2 Mo", "1.2 MB"); a Turn or Ctl is a translator. With tr nil, units are in English.
func NewSessionID ¶ added in v0.2.3
func NewSessionID() string
NewSessionID returns a random identifier, as given to new sessions.
func Run ¶
func Run(cfg Config)
Run opens the window and blocks; the process exits when it is closed.
Example ¶
The smallest application: an agent that answers with one streamed block.
package main
import (
"context"
oriagent "github.com/sitle/ori-agent"
)
func main() {
oriagent.Run(oriagent.Config{
AppName: "Mon assistant",
Agent: oriagent.AgentFunc(func(ctx context.Context, t *oriagent.Turn) error {
b := t.Text()
defer b.Done()
b.Write("Vous avez écrit : " + t.Prompt)
return nil
}),
})
}
Output:
Types ¶
type Agent ¶
Agent produces the assistant side of a conversation turn: an LLM client, a scripted simulation, a rules engine… Run is called on its own goroutine and writes to the transcript through t. It should return promptly once ctx is canceled (the user pressed Stop).
type AgentFunc ¶
AgentFunc adapts a function to the Agent interface.
Example ¶
An agent uses every part of the transcript: reasoning, a task list, tool calls (with a file link) and a final answer. It stops when ctx is canceled.
package main
import (
"context"
"os"
"path/filepath"
"strings"
oriagent "github.com/sitle/ori-agent"
)
func main() {
agent := oriagent.AgentFunc(func(ctx context.Context, t *oriagent.Turn) error {
if t.Thinking { // extended thinking enabled in the settings
th := t.Think()
th.Write("I will list the folder first.")
th.Done()
}
tasks := t.Tasks("List files", "Answer")
entries, err := os.ReadDir(t.WorkDir)
if err != nil {
return err // shown in red in the transcript
}
call := t.Tool("Bash", "ls")
var names []string
for _, e := range entries {
names = append(names, e.Name())
}
call.Done(strings.Join(names, "\n"))
tasks.Advance(0)
if err := ctx.Err(); err != nil { // the user pressed Stop
return err
}
t.Tool("Read", "go.mod").File(filepath.Join(t.WorkDir, "go.mod")).Done("module …")
b := t.Text()
b.Write("The folder has " + itoa(len(entries)) + " entries.")
b.Done()
tasks.Set(1, oriagent.TaskDone)
return nil
})
oriagent.Run(oriagent.Config{Agent: agent})
}
func itoa(n int) string {
if n == 0 {
return "0"
}
var b []byte
for ; n > 0; n /= 10 {
b = append([]byte{byte('0' + n%10)}, b...)
}
return string(b)
}
Output:
type App ¶
type App struct {
// contains filtered or unexported fields
}
App is the running shell. All its state is guarded by mu: the frame handler holds it, background work goes through update.
type ApprovalRequest ¶ added in v0.2.3
type ApprovalRequest struct {
Title string // what the agent wants to do, e.g. "Modifier main.go"
Detail string // the command or other detail, shown as code
// With Diff, the change from Old to New is shown.
Diff bool
Old, New string
// AllowSession offers "Allow for this session" besides allow and deny.
AllowSession bool
}
ApprovalRequest is what an agent asks the user to allow: a command to run, a file to change… ori-agent shows it and collects the answer; the agent decides what needs approval.
type Attachment ¶
type Attachment struct {
Path, Name, Ext string // Ext is lower case, without the dot
Size int64
ImageSize image.Point // for images, once decoded
// contains filtered or unexported fields
}
func NewAttachment ¶
func NewAttachment(path string) (*Attachment, error)
NewAttachment describes an existing file as an already uploaded attachment.
func (*Attachment) IsImage ¶
func (t *Attachment) IsImage() bool
type Block ¶
type Block struct {
// contains filtered or unexported fields
}
Block is a text or reasoning block being streamed.
type Command ¶
Command is a slash command. Desc and Args may be translation keys. Args is a usage hint shown in the palette: "<x>" means required (picking the command only completes it), "[x]" optional. Run returns the text logged in the transcript ("" logs nothing).
Example ¶
A slash command acts on the application through Ctl. Desc can be a translation key or plain text.
package main
import (
oriagent "github.com/sitle/ori-agent"
)
func main() {
hello := &oriagent.Command{
Name: "hello",
Args: "[name]",
Desc: "Say hello",
Run: func(c *oriagent.Ctl, args string) string {
if args == "" {
args = "world"
}
c.Notify("Hello sent")
return "Hello, " + args + "!" // logged in the transcript
},
}
oriagent.Run(oriagent.Config{Commands: []*oriagent.Command{hello}})
}
Output:
type Config ¶
type Config struct {
AppName string // title bar; default "Assistant"
WindowTitle string // OS window title; default AppName
Logo []byte // SVG, shown in the title bar, empty states and setup
Light, Dark theme.Palette // default: Ori
Fonts []font.FontFace
LightMode bool // start in light mode
// Locale is the interface language ("fr", "en", "en-US"…); empty means
// the OS language when a catalog exists for it. Translations add or
// override catalogs (locale → key → text) on top of Catalogs; keys
// missing from a locale fall back to FallbackLocale (default "fr").
Locale string
FallbackLocale string
Translations map[string]map[string]string
OnLocale func(locale string) // called after the language changes
// Settings, when set, are the initial values of the Configuration page
// and take precedence over WorkDir, LightMode and Locale (a WorkDir or
// Locale that cannot be used keeps the Config one). OnSettings receives
// the new values whenever one of them changes: a setup toggle, model,
// theme or language, the title bar theme button, /model, /theme, /lang,
// or the working directory applied by the setup's Finish. It is called
// at the end of the frame, on the UI goroutine with the state locked:
// it must return quickly (save in a goroutine of its own if needed).
Settings *Settings
OnSettings func(Settings)
Agent Agent // default: a placeholder that explains no agent is set
WorkDir string
Models []Model
User User
// OnProfile is called with the edited fields when the user saves the
// Profile page, and OnLogout when they sign out from it. Both run on a
// goroutine of their own while the page buttons wait; the User returned
// by OnProfile (which may normalize it) replaces the fields, an error is
// shown and keeps the edits. Nil keeps the profile in memory and only
// simulates the sign-out.
OnProfile func(ctx context.Context, u User) (User, error)
OnLogout func(ctx context.Context) error
ProfileLock ProfileLock // read-only Profile page fields
// OnNewProject creates a project, such as a workspace folder, from the
// name and description the user typed. When it is set, the sidebar's
// main button opens that form instead of starting a session (the + of
// each project starts one). It runs on a goroutine of its own; an error
// is shown in the form, which keeps the input.
OnNewProject func(ctx context.Context, name, description string) (*Project, error)
// OnUpdateProject saves the edits made on a project's page (opened by
// the gear of its sidebar row) and returns them as kept, and
// OnDeleteProject removes a project that is not Permanent. Both run on
// a goroutine of their own; an error stays on the page. Without
// OnUpdateProject the edits only apply in memory; without
// OnDeleteProject the page has no remove button.
OnUpdateProject func(ctx context.Context, p *Project, edit ProjectEdit) (ProjectEdit, error)
OnDeleteProject func(ctx context.Context, p *Project) error
// ProjectFiles lists the files shown in a Files section of a project's
// page, such as the files attached in its sessions; nil hides the
// section. It is called on a goroutine of its own when the page opens.
ProjectFiles func(p *Project) []ProjectFile
Devices []*Device // profile's connected devices; empty hides the section
Projects []*Project // demo data; default: one empty session
Commands []*Command // added to the built-in ones
Pages []Page
Dictation Dictation // default: simulated
Pomodoro PomodoroConfig
Disable Features
Placeholder string // composer hint
ModeLabel string // chip in the composer ("-" hides it)
EmptyTitle string // empty session
EmptySubtitle string // default: the working directory
// Startup state.
StartView string // "chat" (default), "setup", "profile" or a Page ID
SetupStep int // 1-based, with StartView "setup"
Attach []string // files attached to the composer at startup
Preview string // file opened in the preview pane at startup
// Convert renders in the preview pane the files it does not read itself
// (Word, Excel, PowerPoint…): as a PDF or as Markdown, in the
// background. nil, or a nil result: shown as a binary file.
Convert preview.Converter
Width, Height unit.Dp // default 1280×820
}
Example (Profile) ¶
The application saves the Profile page and handles the sign-out; a /login command refreshes the profile and the models from its own turn.
package main
import (
"context"
oriagent "github.com/sitle/ori-agent"
)
func main() {
login := &oriagent.Command{Name: "login", Desc: "Sign in", Run: func(c *oriagent.Ctl, _ string) string {
err := c.RunTurn("", func(ctx context.Context, t *oriagent.Turn) error {
// … sign in, then:
t.SetUser(oriagent.User{First: "Hina", Last: "Teriitahi", Email: "hina@example.pf"})
t.SetModels([]oriagent.Model{{Name: "Fast"}, {Name: "Smart"}})
return nil
})
if err != nil {
return err.Error()
}
return ""
}}
oriagent.Run(oriagent.Config{
Commands: []*oriagent.Command{login},
ProfileLock: oriagent.ProfileLock{Email: true}, // from the identity provider
OnProfile: func(ctx context.Context, u oriagent.User) (oriagent.User, error) {
// Runs on its own goroutine: save u, return it as saved.
return u, nil
},
OnLogout: func(ctx context.Context) error { return nil },
})
}
Output:
type Ctl ¶
type Ctl struct {
// contains filtered or unexported fields
}
Ctl is what a slash command can do to the application. It is only valid during Command.Run, which runs on the UI goroutine with the state locked: long work must go through RunTurn (or a goroutine of its own).
func (*Ctl) LanguageName ¶
LanguageName is a locale's own name ("Français", "English").
func (*Ctl) NewSession ¶
func (c *Ctl) NewSession()
func (*Ctl) NewSessionIn ¶ added in v0.2.0
NewSessionIn selects an empty session of p, or starts one in it.
func (*Ctl) Open ¶
Open shows a file in the preview pane; relative paths are resolved against the working directory of the current session.
func (*Ctl) RunTurn ¶
RunTurn starts a turn in the current session; fn nil means the configured Agent. The prompt (if any) is shown as the user's message. It fails when the session is already busy.
func (*Ctl) SetModels ¶ added in v0.2.0
SetModels replaces the model list; the selected model stays when its name is still in the list, else the first one is selected.
func (*Ctl) ToggleSidebar ¶
func (c *Ctl) ToggleSidebar()
func (*Ctl) ToggleVoice ¶
func (c *Ctl) ToggleVoice()
type D ¶
type D = layout.Dimensions
type Decision ¶ added in v0.2.3
type Decision int
Decision is the user's answer to an ApprovalRequest.
type Dictation ¶
Dictation turns speech into text for the composer. Start begins capture; Stop ends it and returns the transcript (it may block: it runs on its own goroutine). Plug a real speech-to-text engine here.
type Features ¶
type Features struct {
Voice, Pomodoro, Attachments, Preview bool
Setup, Profile, ThemeToggle bool
BuiltinCommands bool
}
Features turns built-in parts off; the zero value enables everything.
type Headless ¶ added in v0.4.0
type Headless struct {
// Approve answers the approval requests of the agent (Turn.Approve), on
// the agent's goroutine; nil denies them.
Approve func(ApprovalRequest) Decision
// contains filtered or unexported fields
}
Headless runs an agent without a window, through the same Turn as the application: for tests, evaluation benches and scripts. The transcript of each session can be read afterwards (Session.Messages).
func NewHeadless ¶ added in v0.4.0
NewHeadless prepares cfg.Agent to run without a window; the translations of cfg are used for the texts the agent writes through the turn.
Example ¶
An agent runs without a window through the same Turn, for tests and evaluation benches; the transcript is read from the returned session.
package main
import (
"context"
"fmt"
oriagent "github.com/sitle/ori-agent"
)
func main() {
h := oriagent.NewHeadless(oriagent.Config{Agent: oriagent.AgentFunc(func(ctx context.Context, t *oriagent.Turn) error {
d, err := t.Approve(ctx, oriagent.ApprovalRequest{Title: "Run go test", Detail: "go test ./..."})
if err != nil || d == oriagent.Deny {
return err
}
b := t.Text()
b.Write("Tests pass in " + t.WorkDir)
b.Done()
return nil
})})
h.Approve = func(r oriagent.ApprovalRequest) oriagent.Decision { return oriagent.Allow }
s, err := h.Run(context.Background(), nil, "test it", nil, oriagent.TurnOptions{WorkDir: "/ws"})
if err != nil {
panic(err)
}
fmt.Println(s.Messages[len(s.Messages)-1].Text)
}
Output: Tests pass in /ws
type HistoryEntry ¶
HistoryEntry is a past exchange, for agents that send context to a model.
type Kind ¶
type Kind int
Kind is the type of a transcript item.
const ( KindUser Kind = iota // user bubble, with optional attachments KindAssistant // assistant text KindThinking // collapsible reasoning KindTool // tool call with expandable output KindTasks // task list KindCommand // slash command and its output KindNotice // interruption or error KindApproval // a request the user allows or denies (Turn.Approve) )
type Leveler ¶
type Leveler interface {
Level() float32
}
Leveler is optionally implemented by a Dictation to drive the level meter with the real input level, in [0,1]. Without it the meter is simulated.
type LocaleSetter ¶
type LocaleSetter interface {
SetLocale(locale string)
}
LocaleSetter is implemented by parts that follow the interface language, such as a Dictation engine.
type Message ¶
type Message struct {
Kind Kind
Text string
ToolName string
ToolArg string
Output string
Running bool
Tasks []Task
Secs int // thinking duration
Sub *Session // subagent behind an Agent tool call: a click opens it
FilePath string // file behind a tool call: a click previews it
Error bool // KindNotice: an error rather than an interruption
Expanded bool // tool output or reasoning shown
// With HasDiff, a tool call shows the change from DiffOld to DiffNew
// instead of its output (ToolCall.Diff).
HasDiff bool
DiffOld, DiffNew string
Attachments []*Attachment
// contains filtered or unexported fields
}
Message is one transcript item. Agents create them through a Turn; demo transcripts can build them directly.
func ThinkingMsg ¶
func UserMsg ¶
func UserMsg(text string, atts ...*Attachment) *Message
type Page ¶
type Page struct {
ID, Title string
Icon func(gtx layout.Context, c color.NRGBA) layout.Dimensions // optional
Layout func(gtx layout.Context, th *ui.Theme, tr i18n.Translator) layout.Dimensions
}
Page is an extra screen reached from the sidebar. Layout draws the content; the shell adds the title and the centered, scrollable column. tr translates in the current interface language.
Example ¶
A page is an extra screen in the sidebar, drawn with the ui kit and translated through tr.
package main
import (
"gioui.org/font"
"gioui.org/layout"
oriagent "github.com/sitle/ori-agent"
"github.com/sitle/ori-agent/i18n"
"github.com/sitle/ori-agent/ui"
)
func main() {
about := oriagent.Page{
ID: "about",
Title: "about.title", // translation key
Layout: func(gtx layout.Context, th *ui.Theme, tr i18n.Translator) layout.Dimensions {
return th.Section(gtx, tr.T("about.title"), "", th.Label(14, tr.T("about.body"), th.Text, font.Normal).Layout)
},
}
oriagent.Run(oriagent.Config{
Pages: []oriagent.Page{about},
Translations: map[string]map[string]string{
"fr": {"about.title": "À propos", "about.body": "Version de démonstration."},
"en": {"about.title": "About", "about.body": "Demo version."},
},
})
}
Output:
type Permissions ¶ added in v0.2.0
Permissions are what the agent may do in a project's sessions; they are given to it in Turn.AllowCommands and Turn.AskEdits.
type Pomodoro ¶
type Pomodoro struct {
// contains filtered or unexported fields
}
Pomodoro is a countdown driven by the wall clock: focus periods with a long pause every four.
type PomodoroConfig ¶
type ProfileLock ¶ added in v0.2.0
type ProfileLock struct {
First, Last, Email, Service, Role bool
}
ProfileLock makes Profile page fields read-only, for values the application does not let the user change (from a directory, an identity provider…).
type Project ¶
type Project struct {
Name string
Description string
// WorkDir is the folder of the project: Turn.WorkDir for its sessions.
// Empty: the folder of the configuration.
WorkDir string
// Permissions of the project's sessions; nil: the Configuration's.
Permissions *Permissions
// Permanent projects cannot be removed from their page.
Permanent bool
Sessions []*Session
Open bool
// contains filtered or unexported fields
}
Project groups sessions in the sidebar.
func NewProject ¶
NewProject returns an open project holding sessions (first on top).
Example ¶
Demo data fills the sidebar tree and transcripts at startup.
package main
import (
oriagent "github.com/sitle/ori-agent"
)
func main() {
s := &oriagent.Session{Title: "Fix the login page", Messages: []*oriagent.Message{
oriagent.UserMsg("The login button does nothing."),
oriagent.ThinkingMsg("The click handler is probably not bound.", 3),
oriagent.ToolMsg("Read", "login.go", " 1 package main"),
oriagent.TextMsg("Fixed: the handler is now registered."),
}}
s.Spawn("Run the tests") // a subagent under the session
oriagent.Run(oriagent.Config{Projects: []*oriagent.Project{oriagent.NewProject("web", s)}})
}
Output:
type ProjectEdit ¶ added in v0.2.0
type ProjectEdit struct {
Name string
Description string
Permissions *Permissions // nil when the project has none of its own
}
ProjectEdit is what the user changed on a project's page.
type ProjectFile ¶ added in v0.2.2
type ProjectFile struct {
Name string
Detail string // size, date, version, checksum…
Path string // opened in the preview pane on click; empty: not clickable
Warning string // shown in red when set, such as "changed since added"
}
ProjectFile is a row of the Files section of a project's page, such as a file the user attached in its sessions.
type Session ¶
type Session struct {
// ID identifies the session for the agent (Turn.SessionID), so that it
// finds its own records again. Applications set it on the sessions
// they restore; ori-agent gives one to the others.
ID string
Title string
Messages []*Message
Children []*Session
Busy bool
Open bool // subagents shown in the sidebar
// contains filtered or unexported fields
}
Session is a conversation; Children are the subagents it spawned.
type Settings ¶ added in v0.2.0
type Settings struct {
WorkDir string `json:"workDir,omitempty"` // ignored at startup if it is not a folder
AllowCommands bool `json:"allowCommands"`
AskEdits bool `json:"askEdits"`
Thinking bool `json:"thinking"` // extended thinking
Notifications bool `json:"notifications"`
Model string `json:"model,omitempty"` // a Model.Name; empty or unknown means the first model
Dark bool `json:"dark"`
Locale string `json:"locale,omitempty"` // ignored at startup if no catalog matches
}
Settings are the values of the Configuration page, so that an application can restore them at startup (Config.Settings) and keep them when the user changes them (Config.OnSettings). The JSON tags make them easy to save in a file; ori-agent itself stores nothing.
Example ¶
The application keeps the Configuration page values in a file of its own: it restores them at startup and saves them whenever the user changes one.
package main
import (
"encoding/json"
"os"
"path/filepath"
oriagent "github.com/sitle/ori-agent"
)
func main() {
path := filepath.Join(os.TempDir(), "settings.json")
set := oriagent.DefaultSettings() // missing fields keep their default
if data, err := os.ReadFile(path); err == nil {
_ = json.Unmarshal(data, &set)
}
oriagent.Run(oriagent.Config{
Models: []oriagent.Model{{Name: "Fast"}, {Name: "Smart"}},
Settings: &set,
OnSettings: func(s oriagent.Settings) { // UI goroutine: do not block
data, _ := json.MarshalIndent(s, "", " ")
go os.WriteFile(path, data, 0o600)
},
})
}
Output:
func DefaultSettings ¶ added in v0.2.0
func DefaultSettings() Settings
DefaultSettings are the values used when Config.Settings is nil. Decode a saved file over them, so that missing fields keep their default.
type SimDictation ¶
SimDictation captures nothing and returns canned phrases in turn, in the interface language (Phrases maps a locale to its phrases).
func (*SimDictation) SetLocale ¶
func (d *SimDictation) SetLocale(locale string)
func (*SimDictation) Start ¶
func (d *SimDictation) Start() error
func (*SimDictation) Stop ¶
func (d *SimDictation) Stop() (string, error)
type Task ¶
type Task struct {
Text string
Status TaskStatus
}
type TaskList ¶
type TaskList struct {
// contains filtered or unexported fields
}
TaskList is a live checklist.
func (*TaskList) Set ¶
func (l *TaskList) Set(i int, st TaskStatus)
type ToolCall ¶
type ToolCall struct {
// contains filtered or unexported fields
}
ToolCall is a tool invocation shown in the transcript.
func (*ToolCall) Diff ¶ added in v0.2.3
Diff shows the change the call made to a file, from old to new, in place of its output, unfolded; the header counts the lines added and removed.
type Turn ¶
type Turn struct {
Prompt string
Attachments []*Attachment
History []HistoryEntry // the session before this turn
Thinking bool // extended thinking is enabled in the settings
AllowCommands bool // the settings let the agent run commands (the agent enforces it)
AskEdits bool // the settings ask to confirm file edits (the agent enforces it)
Model Model
WorkDir string
Locale string // interface language, so the agent can answer in it
// SessionID is the Session.ID of the turn's session, stable across
// turns and, when the application restores sessions with their ID,
// across launches.
SessionID string
// contains filtered or unexported fields
}
Turn is the agent's handle on one turn. Its methods are safe to call from any goroutine: they lock the UI state and request a redraw.
func (*Turn) Approve ¶ added in v0.2.3
Approve shows req in the transcript and waits for the user's answer. A subagent's request is shown in its root session, naming the subagent, where the user is working. When ctx is canceled (Stop), the request is withdrawn and ctx's error returned with Deny.
func (*Turn) SetModels ¶ added in v0.2.0
SetModels replaces the model list, as Ctl.SetModels. The running turn keeps its Model.
func (*Turn) SetUser ¶ added in v0.2.0
SetUser replaces the profile (Profile page and sidebar footer), for example after a sign-in turn.
func (*Turn) Subagent ¶
Subagent spawns a child session under the current one, shown in the sidebar tree and as an "Agent" tool call here. Write the subagent's work through the returned turn, then call its Finish.
Example ¶
A subagent appears under the session in the sidebar tree, and as an "Agent" tool call that opens it.
package main
import (
"context"
oriagent "github.com/sitle/ori-agent"
)
func main() {
_ = oriagent.AgentFunc(func(ctx context.Context, t *oriagent.Turn) error {
sub := t.Subagent("Explore the docs", "Read every Markdown file and summarize.")
sub.Tool("Glob", "**/*.md").Done("README.md\ndocs/guide.md")
sub.Finish("2 documents found.") // becomes the parent's tool output
b := t.Text()
b.Write("The subagent found 2 documents.")
b.Done()
return nil
})
}
Output:
func (*Turn) T ¶
T translates key in the turn's language, with the framework catalogs and Config.Translations: agents can keep their texts there too.
type TurnOptions ¶ added in v0.4.0
type TurnOptions struct {
Thinking bool
AllowCommands bool
AskEdits bool
Model Model
WorkDir string
Locale string // default: the configuration's
}
TurnOptions are the settings of a headless turn, which the window takes from the Configuration page and the selected model.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
anna
command
Command anna is "Anna Assistant", the demo application of the ori-agent framework: it configures the shell, provides demo data, and keeps what ori-agent leaves to the application (settings, profile, projects) in a folder of its own (store.go).
|
Command anna is "Anna Assistant", the demo application of the ori-agent framework: it configures the shell, provides demo data, and keeps what ori-agent leaves to the application (settings, profile, projects) in a folder of its own (store.go). |
|
minimal
command
Command minimal is the smallest ori-agent application: an agent that reasons briefly, shows a tool call and echoes the prompt.
|
Command minimal is the smallest ori-agent application: an agent that reasons briefly, shows a tool call and echoes the prompt. |
|
Package i18n translates interface strings.
|
Package i18n translates interface strings. |
|
Package preview renders read-only documents in a pane: Markdown (the block subset READMEs use), source code with line numbers, PDF (rasterized by PDFium compiled to WebAssembly, pure Go) and images.
|
Package preview renders read-only documents in a pane: Markdown (the block subset READMEs use), source code with line numbers, PDF (rasterized by PDFium compiled to WebAssembly, pure Go) and images. |
|
Package sim is a scripted agent for demos and UI work: no model is called, but its tool calls really run against the working directory (listing, reading files).
|
Package sim is a scripted agent for demos and UI work: no model is called, but its tool calls really run against the working directory (listing, reading files). |
|
Package theme holds color palettes.
|
Package theme holds color palettes. |
|
Package ui is the widget kit of ori-agent: drawing primitives, form controls, icons and overlays, all drawn with a Theme.
|
Package ui is the widget kit of ori-agent: drawing primitives, form controls, icons and overlays, all drawn with a Theme. |


