agents

package
v3.0.1-alpha9 Latest Latest
Warning

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

Go to latest
Published: Jul 5, 2026 License: AGPL-3.0 Imports: 17 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// DefaultAppName is the default application name for the ADK runner.
	DefaultAppName = "WeOS"
)
View Source
const OrchestratorAppName = "weos-agent"

OrchestratorAppName scopes ADK sessions for the in-app agent.

Variables

View Source
var ErrEpisodicMemoryUnavailable = errors.New(
	"episodic memory unavailable: install the memory preset to record conversation turns")

ErrEpisodicMemoryUnavailable is returned by an EpisodeRecorder when the note resource type does not exist — i.e. the memory preset is not installed. The orchestrator treats it as "episodic memory is off" (one info line, no per-turn error noise) rather than a failure.

View Source
var ErrNotConfigured = errors.New("agent not configured: set the Gemini API key to enable the in-app agent")

ErrNotConfigured is returned when no LLM key is configured; the in-app agent surface degrades to a clear signal instead of failing obscurely (mirrors how #386 consolidation no-ops without a key).

Functions

func ApplyResponseSchemaFromContext

func ApplyResponseSchemaFromContext(
	ctx agent.Context, req *model.LLMRequest,
) (*model.LLMResponse, error)

ApplyResponseSchemaFromContext is a BeforeModelCallback that applies the response schema from context (when set by RunAgent) to the LLM request so the model returns structured output.

func BuildSkillAgent

func BuildSkillAgent(def entities.SkillDefinition, m model.LLM, toolset tool.Toolset) (agent.Agent, error)

BuildSkillAgent turns a validated skill definition into a runnable ADK agent. The shared toolset is filtered down to the skill's allowlist, and the declared mode maps to the ADK delegation mode that governs how an orchestrator hands work to the skill. The definition is data — this factory is the only place a skill becomes code, which is what lets projects add skills without recompiling.

func BuildSkillRootAgent

func BuildSkillRootAgent(def entities.SkillDefinition, m model.LLM, toolset tool.Toolset) (agent.Agent, error)

BuildSkillRootAgent builds the skill as a conversation's root agent (the direct-invocation path, bypassing the coordinator). The declared delegation mode is deliberately ignored — it governs how a PARENT invokes the skill, and a root has no parent. Chat is also the only mode the ADK runner accepts for a root ("root agent must be a chat LlmAgent"): a ModeSingleTurn root would fail every turn outright, and a ModeTask root would self-install a finish_task tool with no parent to consume it. The skill's instructions ride along unchanged either way.

func ParseFactCandidates

func ParseFactCandidates(out string) ([]entities.FactCandidate, error)

ParseFactCandidates parses the model's JSON reply into fact candidates, tolerating markdown code fences some models wrap JSON in.

func RunAgent

func RunAgent(
	ctx context.Context, a agent.Agent, appName, userID, sessionID, userInput string,
	responseSchema *genai.Schema, fileParts ...*genai.Part,
) (string, error)

RunAgent runs the given agent with the user input and returns the concatenated text from all non-partial LLM response events.

Types

type EpisodeRecorder

type EpisodeRecorder func(ctx context.Context, conversationID, userID, message, reply string) error

EpisodeRecorder persists one completed turn as episodic memory (the application layer records it as a note resource, which is the type #386 background consolidation distills facts from). Recording failures must never fail the turn — the orchestrator logs and moves on.

type EventSink

type EventSink func(entities.AgentEvent)

EventSink receives the events of one streamed turn.

type GeminiFactExtractor

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

GeminiFactExtractor implements entities.FactExtractor on Google ADK/Gemini. It is the first BYOK provider; alternatives implement the same port.

func NewGeminiFactExtractor

func NewGeminiFactExtractor(m model.LLM) *GeminiFactExtractor

NewGeminiFactExtractor wraps a configured ADK model as a FactExtractor.

func (*GeminiFactExtractor) ExtractFacts

ExtractFacts prompts the model with the observation plus known facts and parses the structured reply.

type Orchestrator

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

Orchestrator is the in-app agent: a Chat-mode coordinator that routes each request to the right skill sub-agent, built fresh from the current skill definitions so skill changes apply without a restart. It satisfies the application layer's ConversationalAgent interface; ADK types never cross this package boundary.

func NewOrchestrator

func NewOrchestrator(m model.LLM, sessions session.Service, logger entities.Logger) *Orchestrator

NewOrchestrator assembles the orchestrator. model and sessions may be nil when the instance has no LLM configured — Converse then returns ErrNotConfigured and the rest of the app is unaffected.

func (*Orchestrator) Configured

func (o *Orchestrator) Configured() bool

Configured reports whether the in-app agent can serve conversations.

func (*Orchestrator) Converse

func (o *Orchestrator) Converse(
	ctx context.Context, conversationID, userID, message string,
) (widgets.Response, error)

Converse runs one turn of a conversation. conversationID maps to a durable ADK session, so multi-turn exchanges — and, with a DB-backed session service, restarts — keep their history. ctx must carry the caller's identity (it is the context tools execute under) and must be request-scoped: the per-turn toolset session lives exactly as long as ctx, so a non-cancellable context would leak an in-memory MCP session per turn.

func (*Orchestrator) ConverseStream

func (o *Orchestrator) ConverseStream(
	ctx context.Context, conversationID, userID, message, skill string, emit EventSink,
) error

ConverseStream runs one turn, emitting text deltas as the model produces them, an input_requested event when a mutating tool awaits the user's confirmation, and finally the validated widgets plus done. A non-empty skill converses with that one skill directly (built as the root agent, no coordinator routing); empty keeps the coordinator.

func (*Orchestrator) History

func (o *Orchestrator) History(ctx context.Context, conversationID, userID string) ([]entities.AgentMessage, error)

History returns the conversation so far, oldest first. A conversation that does not exist yet has an empty history.

func (*Orchestrator) ResumeConfirmation

func (o *Orchestrator) ResumeConfirmation(
	ctx context.Context, conversationID, userID, callID string, confirmed bool,
	payload map[string]any, skill string, emit EventSink,
) error

ResumeConfirmation answers a pending tool confirmation (per the ADK tool-confirmation protocol) and streams the rest of the turn. The pending call lives in the durable session, so a confirmation survives refreshes and restarts. A non-nil payload rides the confirmation response into ADK's ToolConfirmation.Payload — the toolset substitutes it for the call's arguments on approval (approve-with-edits) — and is durable for the same reason the confirmation is. On a rejection the payload is dropped: nothing executes, so persisting edited args would only bloat the session. skill must name the same skill the paused turn ran as (the resumed turn rebuilds the same root); empty means the coordinator.

func (*Orchestrator) SetEpisodeRecorder

func (o *Orchestrator) SetEpisodeRecorder(r EpisodeRecorder)

SetEpisodeRecorder wires turn recording (called from the application layer's fx wiring).

func (*Orchestrator) SetSkillSource

func (o *Orchestrator) SetSkillSource(s SkillSource)

SetSkillSource wires the skill registry (called from the application layer's fx wiring).

func (*Orchestrator) SetToolsetFactory

func (o *Orchestrator) SetToolsetFactory(f ToolsetFactory, defaultTools []string)

SetToolsetFactory wires the tool surface once it exists (the serve command builds it after the MCP server). defaultTools are the read-only tool names the coordinator may use directly when no skill matches.

type SkillSource

type SkillSource func(ctx context.Context) ([]entities.SkillDefinition, error)

SkillSource supplies the current skill definitions (the application layer's SkillRegistry, injected as a function to keep this package free of application imports).

type ToolsetFactory

type ToolsetFactory func(ctx context.Context) (tool.Toolset, error)

ToolsetFactory opens a tool surface for one conversation context. The context carries the caller's identity — service-layer authorization reads it — so the orchestrator asks for a fresh toolset per turn rather than sharing one across users.

Jump to

Keyboard shortcuts

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