provider/openai: - Fix doubled tool call args (argsComplete flag): Ollama sends complete args in the first streaming chunk then repeats them as delta, causing doubled JSON and 400 errors in elfs - Handle fs: prefix (gemma4 uses fs:grep instead of fs.grep) - Add Reasoning field support for Ollama thinking output cmd/gnoma: - Early TTY detection so logger is created with correct destination before any component gets a reference to it (fixes slog WARN bleed into TUI textarea) permission: - Exempt spawn_elfs and agent tools from safety scanner: elf prompt text may legitimately mention .env/.ssh/credentials patterns and should not be blocked tui/app: - /init retry chain: no-tool-calls → spawn_elfs nudge → write nudge (ask for plain text output) → TUI fallback write from streamBuf - looksLikeAgentsMD + extractMarkdownDoc: validate and clean fallback content before writing (reject refusals, strip narrative preambles) - Collapse thinking output to 3 lines; ctrl+o to expand (live stream and committed messages) - Stream-level filter for model pseudo-tool-call blocks: suppresses <<tool_code>>...</tool_code>> and <<function_call>>...<tool_call|> from entering streamBuf across chunk boundaries - sanitizeAssistantText regex covers both block formats - Reset streamFilterClose at every turn start
70 lines
1.6 KiB
Go
70 lines
1.6 KiB
Go
package session
|
|
|
|
import (
|
|
"somegit.dev/Owlibou/gnoma/internal/engine"
|
|
"somegit.dev/Owlibou/gnoma/internal/stream"
|
|
)
|
|
|
|
// SessionState tracks the current state of a session.
|
|
type SessionState int
|
|
|
|
const (
|
|
StateIdle SessionState = iota
|
|
StateStreaming
|
|
StateToolExec
|
|
StateCancelled
|
|
StateError
|
|
StateClosed
|
|
)
|
|
|
|
func (s SessionState) String() string {
|
|
switch s {
|
|
case StateIdle:
|
|
return "idle"
|
|
case StateStreaming:
|
|
return "streaming"
|
|
case StateToolExec:
|
|
return "tool_exec"
|
|
case StateCancelled:
|
|
return "cancelled"
|
|
case StateError:
|
|
return "error"
|
|
case StateClosed:
|
|
return "closed"
|
|
default:
|
|
return "unknown"
|
|
}
|
|
}
|
|
|
|
// Status holds observable session state.
|
|
type Status struct {
|
|
State SessionState
|
|
Provider string
|
|
Model string
|
|
TokensUsed int64
|
|
TokensMax int64
|
|
TokenPercent int // 0-100
|
|
TokenState string // "ok", "warning", "critical"
|
|
TurnCount int
|
|
}
|
|
|
|
// Session is the boundary between UI and engine.
|
|
// All communication is via channels. No shared mutable state.
|
|
type Session interface {
|
|
// Send submits user input and begins an agentic turn.
|
|
Send(input string) error
|
|
// SendWithOptions is like Send but applies per-turn engine options.
|
|
SendWithOptions(input string, opts engine.TurnOptions) error
|
|
// Events returns the channel that receives streaming events.
|
|
// A new channel is created per Send(). Closed when the turn completes.
|
|
Events() <-chan stream.Event
|
|
// TurnResult returns the completed Turn after Events() is drained.
|
|
TurnResult() (*engine.Turn, error)
|
|
// Cancel aborts the current turn.
|
|
Cancel()
|
|
// Close shuts down the session.
|
|
Close() error
|
|
// Status returns current session state.
|
|
Status() Status
|
|
}
|