agentic

package
v0.2.9 Latest Latest
Warning

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

Go to latest
Published: Aug 16, 2026 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package agentic shared_aliases.go — re-exports rysh-shared/agentic types.

Index

Constants

This section is empty.

Variables

View Source
var ApprovalRequestSubject = sharedagentic.ApprovalRequestSubject

ApprovalRequestSubject returns the NATS subject for approval requests for a pane.

View Source
var ApprovalResponseSubject = sharedagentic.ApprovalResponseSubject

ApprovalResponseSubject returns the NATS subject for approval responses for a pane.

View Source
var NewApprovalManager = sharedagentic.NewApprovalManager

NewApprovalManager creates a new ApprovalManager for a pane.

Functions

func BuildWebModeBlock

func BuildWebModeBlock(profile, url string) string

BuildWebModeBlock renders the browser-automation protocol appended to a web-mode pane's per-turn env block. It gives Ask Rysh prompts the observe→act→verify discipline and tells the model which authenticated browser (profile) it is driving. Rendered per turn, so enabling/disabling web mode or switching profile is picked up on the next prompt.

func LoadProjectMemory

func LoadProjectMemory(workDir string) string

LoadProjectMemory gathers durable memory for the given working directory:

  • the user-global file at ~/.rysh/RYSH.md (lowest precedence), and
  • every RYSH.md found while walking from the filesystem root down to workDir (so the nearest, most-specific file appears last).

The result is formatted for injection into the system prompt. It returns "" when no memory files exist.

func ProviderUsable

func ProviderUsable(cfg config.Config) bool

ProviderUsable exposes providerUsable for pre-flight checks by headless callers (`rysh run`, design 009): a run against the mock fallback provider would end_turn immediately and read as a successful "done", so CI mode must refuse to start when this is false.

func ScopeKey

func ScopeKey(kind ScopeKind, ids ScopeIDs) string

ScopeKey returns a stable string identifying the scope instance selected by kind within ids (e.g. "lane:<laneID>", or "global"). Used as a display/tracking key by the forge/mcp managers.

func ScopeKeyByID

func ScopeKeyByID(kind ScopeKind, id string) string

ScopeKeyByID builds the same key from a scope kind and the bare instance id — used by actor teardown, which knows only its own id.

Types

type ApprovalManager

type ApprovalManager = sharedagentic.ApprovalManager

ApprovalManager handles publishing and subscribing to approval request/response subjects.

type HumanoidChannelTools

type HumanoidChannelTools struct {
	WhatsApp *channels.WhatsAppAdapter
	Email    *channels.EmailAdapter
	Slack    *channels.SlackAdapter
	Drafts   *channels.DraftStore

	// SlackHumanGoverned / EmailHumanGoverned / WhatsAppHumanGoverned gate
	// slack_send, email_send and whatsapp_send (and whatsapp_send_template):
	// when one reports true, only an owner-approved draft may leave on that
	// channel. Read per call so a runtime `##humanoid governance` switch
	// takes effect immediately. All three share one gate implementation —
	// requireApprovedDraft in internal/tools.
	SlackHumanGoverned    func() bool
	EmailHumanGoverned    func() bool
	WhatsAppHumanGoverned func() bool
}

HumanoidChannelTools declares which channel toolsets a humanoid should get.

It exists because a humanoid can have MORE THAN ONE channel contact. The previous per-channel constructors were selected by a switch, so a humanoid configured with both email (human-governed) and Slack received the email toolset and NO slack_* tools at all — it could not draft, let alone send. Registering whichever adapters are present removes that whole class of bug.

type LLMPromptExecutionActor

type LLMPromptExecutionActor = sharedagentic.LLMPromptExecutionActor

LLMPromptExecutionActor manages the agentic conversation and spawns OrchestratorActor instances. This is a type alias — it IS rysh-shared/agentic.LLMPromptExecutionActor.

func NewLLMPromptExecutionActor

func NewLLMPromptExecutionActor(
	paneID string,
	cfg config.Config,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	prov provider.AgenticProvider,
	toolRegistry *tools.ToolRegistry,
	systemPrompt string,
	pipelineOutputSubject string,
) *LLMPromptExecutionActor

NewLLMPromptExecutionActor creates a new LLMPromptExecutionActor using the CLI config struct. This wrapper adapts the CLI config.Config to the shared constructor's signature. The maxIterations defaults to 50 if not set in config (config.AgenticConfig is loaded separately).

type Prompts

type Prompts struct {
	Default             string // system_default.md
	TodoGuidance        string // system_todo_guidance.md
	EnvBlockTemplate    string // system_env_block.md
	EmailGovernance     string // system_email_governance.md
	SubAgent            string // system_sub_agent.md (overrides shared default)
	CompactionSummarize string // system_compaction_summarize.md (overrides shared default)
}

Prompts holds the prompt content used across the agentic system. Each field corresponds to a markdown file in rysh-cli/rysh-cli-agent-prompts/.

Empty fields fall back to the built-in constants below. Production main.go populates this from the embedded //go:embed FS at startup; tests typically leave it nil to exercise the fallbacks.

func (*Prompts) ApplySharedOverrides

func (p *Prompts) ApplySharedOverrides()

ApplySharedOverrides forwards the sub-agent and compaction prompts (if non-empty) into the rysh-shared agentic package's exported variables. Those vars are consulted by code that runs INSIDE rysh-shared (spawned child orchestrators, compaction summarisation) and cannot easily reach back into rysh-cli; pushing the values down is simpler than threading them through every constructor.

type ScopeIDs

type ScopeIDs struct {
	TabID   string
	LaneID  string
	GroupID string
	PaneID  string
}

ScopeIDs identifies the concrete scope instances an execution belongs to. Any field may be empty (e.g. a tab-only context), in which case that level is skipped and the next-wider scope becomes the parent.

func ParseScopeHint

func ParseScopeHint(s string) ScopeIDs

ParseScopeHint is the inverse of ScopeIDs.Hint.

func (ScopeIDs) Hint

func (ids ScopeIDs) Hint() string

Hint encodes the scope ids into a compact opaque string carried on a prompt (MsgAgenticPrompt.ScopeHint), so an agent resolves tools against the invoking pane's scope. Format: "tab|lane|group|pane".

type ScopeKind

type ScopeKind int

ScopeKind identifies a level in the tool-visibility hierarchy. A tool enabled at a given scope is visible to AI executions whose pane falls under that scope. Widening order: Pane ⊂ Group ⊂ Lane ⊂ Tab ⊂ Global.

const (
	ScopeGlobal ScopeKind = iota // session-wide (built-ins, startup-enabled integrations)
	ScopeTab                     // all panes in a tab (the default for ##integration enable)
	ScopeLane                    // all panes in a lane
	ScopeGroup                   // all panes in a pane-group
	ScopePane                    // a single pane
)

func ParseScope

func ParseScope(s string) (ScopeKind, bool)

ParseScope maps a user-supplied --scope token to a ScopeKind. An empty token defaults to ScopeTab (the documented default). "global" is intentionally not user-selectable — it is the daemon-wide default used at startup — so it is rejected here. Returns ok=false for unrecognized tokens.

func (ScopeKind) String

func (k ScopeKind) String() string

type ScopeRegistries

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

ScopeRegistries owns one tools.ToolRegistry per live scope instance and wires them into parent chains that mirror the actor tree:

pane:{id} → group:{id} → lane:{id} → tab:{id} → global

A pane's per-run Clone() flattens this whole chain (see rysh-shared ToolRegistry.Clone), so a tool registered at, say, a lane registry is visible to every pane in that lane on its next prompt — and to no other lane. Tool registration/unregistration is performed by the forge/mcp managers against the registry returned by RegistryFor; this service only owns the instances and their parent wiring.

It is a plain service (not an actor): its maps are guarded by mu because it is reached from the WorkspaceActor goroutine (enable/disable), pane creation, and per-run clones concurrently. The ToolRegistry instances are independently thread-safe.

func NewScopeRegistries

func NewScopeRegistries(global *tools.ToolRegistry) *ScopeRegistries

NewScopeRegistries creates a service whose global scope is the shared registry (built-ins + startup-enabled integrations live there, exactly as today).

func (*ScopeRegistries) Close

func (s *ScopeRegistries) Close(kind ScopeKind, id string)

Close forgets a scope instance's registry. The actor that owns the scope (Tab/Lane/PaneGroup/Pane) calls this when it stops; because actor teardown cascades, each descendant also calls Close, so no stale parent links survive. Tool unregistration is the manager's responsibility (it tracks what it enabled at each scope and Unregisters before/around Close); this only drops the instance so a later same-id scope starts clean.

func (*ScopeRegistries) Global

func (s *ScopeRegistries) Global() *tools.ToolRegistry

Global returns the session-wide registry (== the shared ToolRegistry).

func (*ScopeRegistries) GroupChainFor

func (s *ScopeRegistries) GroupChainFor(ids ScopeIDs) *tools.ToolRegistry

GroupChainFor returns the registry chain a pane's group sits on (group→lane→tab→global), creating instances as needed. Agents inherit this as their parent so they see the integration tools enabled at the invoking pane's group/lane/tab/global — but not that pane's own pane-scoped or per-pane NATS tools.

func (*ScopeRegistries) PaneChain

func (s *ScopeRegistries) PaneChain(ids ScopeIDs) *tools.ToolRegistry

PaneChain returns a fresh per-pane registry parented at group→lane→tab→global, stored under the pane id. Callers (CreateLLMPromptExecutionActor) register the per-pane NATS tools into it; the orchestrator clones it per run, flattening the whole chain live. Creating fresh each call ensures a re-created pane does not inherit a previous incarnation's per-pane tools.

func (*ScopeRegistries) RegistryFor

func (s *ScopeRegistries) RegistryFor(kind ScopeKind, ids ScopeIDs) *tools.ToolRegistry

RegistryFor returns (creating on first use, along with any missing ancestors) the registry for the scope instance identified by kind within ids. The forge/ mcp managers register a tool's executors into this registry to enable it at that scope.

type Setup

type Setup struct {
	Provider     provider.AgenticProvider
	ToolRegistry *tools.ToolRegistry
	AgenticCfg   config.AgenticConfig
	SystemPrompt string
	// SystemPromptNoEnv is SystemPrompt without the env block. Panes use it as
	// their base prompt and inject a fresh env block per turn (with the live
	// shell cwd) via the actor's env-block provider, instead of the static,
	// daemon-cwd env block baked into SystemPrompt. Falls back to SystemPrompt
	// when empty (e.g. ApplyPrompts was never called, as in some tests).
	SystemPromptNoEnv string
	BgSessions        *tools.BackgroundSessionManager
	// MCP manages external Model Context Protocol servers whose tools are
	// registered into ToolRegistry. Tools registered here (e.g. at startup via
	// BootstrapMCP) are visible to every pane/agent that later clones the
	// registry.
	MCP *mcp.Manager

	// Forge manages generated API integrations (OpenAPI→tool-pack). Like MCP, its
	// tools register into ToolRegistry; BootstrapForge enables persisted
	// integrations at startup so they reach every pane/agent.
	Forge *forge.Manager

	// Scopes owns the per-scope-instance tool registries (tab/lane/group/pane),
	// chained pane→group→lane→tab→global with ToolRegistry as the global root.
	// Per-pane registries are built via Scopes.PaneChain; scoped ##integration /
	// ##mcp enablement registers into Scopes.RegistryFor(scope, ids).
	Scopes *ScopeRegistries

	// Prompts holds the externalised prompt content (loaded from
	// rysh-cli-agent-prompts/ by main.go). Nil = fall back to in-package
	// constants in prompts.go. Set via ApplyPrompts after NewSetup.
	Prompts *Prompts

	// PromptReloader is installed by main.go at startup. When invoked
	// (e.g. via SIGHUP or the ##agent reload-prompts workspace command),
	// it re-reads the layered prompt store from disk and returns a fresh
	// Prompts to apply. The workspace command handler calls Reload() which
	// uses this. Follow-up 2b.
	PromptReloader func() *Prompts

	// Metrics is the in-process metrics sink shared across the orchestrator
	// hierarchy (one per Setup, threaded into every orchestrator created
	// through this Setup). Follow-up 3b.
	Metrics sharedagentic.MetricsSink

	// SecretNAT is the process-wide SecretNAT / ReSet manager (reversible
	// secret translation between rysh and the LLM provider). One isolated
	// Session per pane/agent/humanoid is bound at actor creation. The
	// WorkspaceActor pushes known secrets (##secret store) into it; the
	// ##snat / ##rst command surface reads and mutates it. Never nil after
	// NewSetup/NewSetupAlwaysOn — disabled state is carried inside.
	SecretNAT *secretnat.Manager

	// SessionLLM is the runtime-mutable session default model/effort behind
	// the ##llm command. Provider is wrapped to consult it per call, so a
	// switch applies to every existing pane/agent on its next request.
	// Explicit seats (recipe/config step & judge models) still win. Never nil
	// after NewSetup/NewSetupAlwaysOn.
	SessionLLM *provider.SessionDefaults
	// contains filtered or unexported fields
}

Setup holds the initialized agentic components ready to be attached to a pane.

func NewSetup

func NewSetup(cfg config.Config, plKV nats.KeyValue) *Setup

NewSetup creates the agentic infrastructure from configuration. Returns nil if agentic mode is disabled.

func NewSetupAlwaysOn

func NewSetupAlwaysOn(cfg config.Config, plKV nats.KeyValue) *Setup

NewSetupAlwaysOn creates an agentic Setup regardless of the Enabled flag. This is used when LLMActor has been replaced by LLMPromptExecutionActor and a Setup is always required for prompt handling.

func (*Setup) ApplyPrompts

func (s *Setup) ApplyPrompts(p *Prompts, workDir string)

ApplyPrompts replaces the system prompt with one assembled from the externalised prompt files: default → project memory (RYSH.md) → env block → todo guidance. It also pushes the sub-agent and compaction prompt overrides into the rysh-shared agentic package (where the orchestrator and compaction code consume them).

Production main.go calls this once at startup after NewSetup/NewSetupAlwaysOn. Tests typically skip it so they exercise the fallback consts.

func (*Setup) BootstrapForge

func (s *Setup) BootstrapForge(ctx context.Context)

BootstrapForge enables Forge integrations persisted in <workDir>/.rysh/forge that are marked enabled, registering their tools into the shared registry before panes clone it. No-op when Forge is unavailable.

func (*Setup) BootstrapMCP

func (s *Setup) BootstrapMCP(ctx context.Context)

BootstrapMCP connects to MCP servers persisted in <workDir>/.rysh/mcp.json and registers their tools into the shared registry. It must run at daemon startup, before panes clone the registry, so MCP tools reach every pane and agent. It is a no-op when MCP is unavailable or no servers are configured.

func (*Setup) BuildLiveEnvBlock

func (s *Setup) BuildLiveEnvBlock(workDir string) string

BuildLiveEnvBlock renders the env-block template for workDir using the current Prompts. Panes call this per turn with their live shell cwd so the env block tracks `cd`. Returns "" if no Prompts/template is configured.

func (*Setup) CreateAgentLLMPromptExecutionActor

func (s *Setup) CreateAgentLLMPromptExecutionActor(
	agentName string,
	cfg config.Config,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	systemPrompt string,
	chatOutputPaneID string,
) *LLMPromptExecutionActor

CreateAgentLLMPromptExecutionActor creates a new LLMPromptExecutionActor for an autonomous agent. Unlike CreateLLMPromptExecutionActor (which is for panes), this accepts a custom system prompt and chatOutputPaneID for routing output to a pane's chat buffer.

func (*Setup) CreateHumanoidLLMWithChannelTools

func (s *Setup) CreateHumanoidLLMWithChannelTools(
	name string,
	cfg config.Config,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	systemPrompt string,
	chatOutputPaneID string,
	ct HumanoidChannelTools,
) *LLMPromptExecutionActor

CreateHumanoidLLMWithChannelTools builds a humanoid's LLM actor with every requested channel toolset registered, plus the matching governance prompts.

func (*Setup) CreateLLMPromptExecutionActor

func (s *Setup) CreateLLMPromptExecutionActor(
	ids ScopeIDs,
	cfg config.Config,
	pub *msg.NATSPublisher,
	nc *nats.Conn,
	kvStore nats.KeyValue,
	paneOverride *provider.PaneOverride,
) *LLMPromptExecutionActor

CreateLLMPromptExecutionActor creates a new LLMPromptExecutionActor for the given pane. Per-pane NATS-dependent tools are registered into a cloned registry before spawning the actor, so the shared OrchestratorActor (which clones it again per run) inherits all tools without needing NATS access itself.

paneOverride, when non-nil, is the pane's `##pane provider` holder (design 002 §3.4): the executor's provider is wrapped to consult it per call, so an override installed later applies to the pane's next prompt without respawning this actor.

func (*Setup) Reload

func (s *Setup) Reload() *Prompts

Reload re-runs the installed PromptReloader closure and applies the fresh Prompts via ApplyPrompts. Returns the newly-applied Prompts so the caller can broadcast MsgReloadPrompts to active actors. Returns nil when no reloader is installed (the host hasn't wired up SetPromptReloader).

Follow-up 2b.

Jump to

Keyboard shortcuts

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