extensions

package
v0.5.0-beta Latest Latest
Warning

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

Go to latest
Published: Jul 13, 2026 License: MIT Imports: 31 Imported by: 0

Documentation

Overview

Package extensions implements Kodelet's long-running extension runtime.

Index

Constants

View Source
const (
	// CommandActionPass means the command declined handling and routing should continue.
	CommandActionPass = "pass"
	// CommandActionRespond means the command handled the prompt with a direct UI response.
	CommandActionRespond = "respond"
	// CommandActionRunAgent means the command produced a replacement prompt for the agent.
	CommandActionRunAgent = "runAgent"
)
View Source
const (
	// EventSessionStart is dispatched when the extension runtime starts.
	EventSessionStart = "session.start"
	// EventResourcesDiscover is dispatched before extension resources are finalized.
	EventResourcesDiscover = "resources.discover"
	// EventUserMessage is dispatched after a user prompt is received and before it is added to the conversation.
	EventUserMessage = "user.message"
	// EventAgentInit is dispatched after a system prompt is built and before a model request.
	EventAgentInit = "agent.init"
	// EventAgentStart is dispatched when an agent loop starts.
	EventAgentStart = "agent.start"
	// EventTurnStart is dispatched before each model turn.
	EventTurnStart = "turn.start"
	// EventToolCall is dispatched before a tool executes.
	EventToolCall = "tool.call"
	// EventToolResult is dispatched after a tool executes and before it is rendered/stored.
	EventToolResult = "tool.result"
	// EventTurnEnd is dispatched after one assistant turn completes.
	EventTurnEnd = "turn.end"
	// EventAgentEnd is dispatched when an agent loop has completed.
	EventAgentEnd = "agent.end"
	// EventSessionEnd is dispatched when the extension runtime shuts down.
	EventSessionEnd = "session.end"
)
View Source
const (
	UIInputStatusSubmitted   = "submitted"
	UIInputStatusDismissed   = "dismissed"
	UIInputStatusTimeout     = "timeout"
	UIInputStatusUnavailable = "unavailable"
)

Variables

This section is empty.

Functions

func ContextWithDiagnosticSink

func ContextWithDiagnosticSink(ctx context.Context, sink DiagnosticSink) context.Context

ContextWithDiagnosticSink attaches a diagnostic sink to an extension runtime context.

func ContextWithUIInputBroker

func ContextWithUIInputBroker(ctx context.Context, broker UIInputBroker) context.Context

ContextWithUIInputBroker attaches a UI input broker to the active run context.

func NewUIInputRequestID

func NewUIInputRequestID() string

NewUIInputRequestID returns a unique request ID for UI input prompts.

func SlashCommands

func SlashCommands(commands []Command) []slashcommands.Command

SlashCommands converts extension command registrations to slash commands.

Types

type AgentInitDecision

type AgentInitDecision struct {
	SystemPrompt  string
	AllowedTools  []string
	ToolsModified bool
}

AgentInitDecision is the result of dispatching agent.init handlers.

type Command

type Command struct {
	ExtensionID  string
	Process      *Process
	Registration CommandRegistration
}

Command is an extension command registration bound to its process.

type CommandInvocation

type CommandInvocation struct {
	Raw         string         `json:"raw"`
	CommandName string         `json:"commandName"`
	Args        []string       `json:"args"`
	Flags       map[string]any `json:"flags"`
}

CommandInvocation describes the user prompt that invoked an extension command.

type CommandRegistration

type CommandRegistration struct {
	Name         string         `json:"name"`
	Aliases      []string       `json:"aliases,omitempty"`
	Description  string         `json:"description"`
	InputSchema  map[string]any `json:"inputSchema,omitempty"`
	Kind         string         `json:"kind,omitempty"`
	TimeoutInSec *float64       `json:"timeoutInSec,omitempty"`
}

CommandRegistration is returned by an extension during initialization.

type CommandResult

type CommandResult struct {
	Action     string `json:"action"`
	Response   string `json:"response,omitempty"`
	Prompt     string `json:"prompt,omitempty"`
	RecipeName string `json:"recipeName,omitempty"`
}

CommandResult is returned by extension.command.execute.

type Config

type Config struct {
	Enabled       bool                  `mapstructure:"enabled" json:"enabled" yaml:"enabled"`
	GlobalDir     string                `mapstructure:"global_dir" json:"global_dir" yaml:"global_dir"`
	LocalDir      string                `mapstructure:"local_dir" json:"local_dir" yaml:"local_dir"`
	MaxOutputSize int                   `mapstructure:"max_output_size" json:"max_output_size" yaml:"max_output_size"`
	Allow         []string              `mapstructure:"allow" json:"allow" yaml:"allow"`
	Deny          []string              `mapstructure:"deny" json:"deny" yaml:"deny"`
	Tools         map[string]ToolConfig `mapstructure:"tools" json:"tools" yaml:"tools"`
}

Config contains extension runtime configuration.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns the default extension runtime configuration.

func LoadConfigFromViper

func LoadConfigFromViper() Config

LoadConfigFromViper loads extension configuration from viper.

type Diagnostic

type Diagnostic struct {
	Level     DiagnosticLevel
	Extension string
	Message   string
	Fields    map[string]any
}

Diagnostic is a structured warning or error emitted by an extension.

type DiagnosticLevel

type DiagnosticLevel string

DiagnosticLevel is the severity of an extension diagnostic that may be surfaced by an interactive host.

const (
	DiagnosticLevelWarning DiagnosticLevel = "warning"
	DiagnosticLevelError   DiagnosticLevel = "error"
)

type DiagnosticSink

type DiagnosticSink interface {
	ReportDiagnostic(ctx context.Context, diagnostic Diagnostic)
}

DiagnosticSink receives structured extension diagnostics. Implementations should return promptly so extension stderr processing cannot be blocked by UI rendering.

func DiagnosticSinkFromContext

func DiagnosticSinkFromContext(ctx context.Context) (DiagnosticSink, bool)

DiagnosticSinkFromContext returns the run-scoped diagnostic sink, if one is available.

type Discovery

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

Discovery handles extension discovery.

func NewDiscovery

func NewDiscovery(opts ...DiscoveryOption) (*Discovery, error)

NewDiscovery creates an extension discovery instance.

func (*Discovery) Discover

func (d *Discovery) Discover() ([]Extension, error)

Discover finds extension executables in configured roots.

type DiscoveryOption

type DiscoveryOption func(*Discovery) error

DiscoveryOption configures extension discovery.

func WithConfig

func WithConfig(config Config) DiscoveryOption

WithConfig sets discovery config.

func WithRoots

func WithRoots(roots ...Root) DiscoveryOption

WithRoots replaces discovery roots. Intended for tests.

func WithWorkingDir

func WithWorkingDir(workingDir string) DiscoveryOption

WithWorkingDir sets the working directory for relative path normalization.

type EventBlock

type EventBlock struct {
	Reason string `json:"reason"`
}

EventBlock asks Kodelet to block a mutable/blocking event.

type EventResult

type EventResult struct {
	Input            json.RawMessage    `json:"input,omitempty"`
	Block            *EventBlock        `json:"block,omitempty"`
	Output           json.RawMessage    `json:"output,omitempty"`
	Message          *string            `json:"message,omitempty"`
	SystemPrompt     *SystemPromptPatch `json:"systemPrompt,omitempty"`
	Tools            *ToolListPatch     `json:"tools,omitempty"`
	FollowUpMessages []string           `json:"followUpMessages,omitempty"`
}

EventResult is returned by extension.event.handle.

type Extension

type Extension struct {
	ID           string
	Name         string
	ExecPath     string
	Dir          string
	RootDir      string
	Kind         SourceKind
	PluginPrefix string
	PluginRef    string
}

Extension describes a discovered extension executable.

type ExtensionCallContext

type ExtensionCallContext struct {
	SessionID      string `json:"sessionId,omitempty"`
	ConversationID string `json:"conversationId,omitempty"`
	CWD            string `json:"cwd,omitempty"`
	Provider       string `json:"provider,omitempty"`
	Model          string `json:"model,omitempty"`
	Profile        string `json:"profile,omitempty"`
	RecipeName     string `json:"recipeName,omitempty"`
	InvokedBy      string `json:"invokedBy,omitempty"`
}

ExtensionCallContext is passed to extension tool/event/command calls.

type InitializeResult

type InitializeResult struct {
	Name          string                `json:"name"`
	Version       string                `json:"version,omitempty"`
	Tools         []ToolRegistration    `json:"tools,omitempty"`
	Commands      []CommandRegistration `json:"commands,omitempty"`
	Subscriptions []Subscription        `json:"subscriptions,omitempty"`
}

InitializeResult is returned by extension.initialize.

type Process

type Process struct {
	Extension Extension
	// contains filtered or unexported fields
}

Process is a running extension subprocess.

func StartProcess

func StartProcess(ctx context.Context, ext Extension, config Config, workspaceCWD string) (*Process, error)

StartProcess starts an extension subprocess and initializes its JSON-RPC client.

func (*Process) Close

func (p *Process) Close() error

Close terminates the extension process.

func (*Process) ExecuteCommand

func (p *Process) ExecuteCommand(ctx context.Context, name string, input map[string]any, invocation CommandInvocation, callContext ExtensionCallContext) (*CommandResult, error)

ExecuteCommand invokes an extension-provided command over JSON-RPC.

func (*Process) ExecuteTool

func (p *Process) ExecuteTool(ctx context.Context, name string, input json.RawMessage, callContext ExtensionCallContext) (*ToolExecutionResult, error)

ExecuteTool invokes an extension-provided tool.

func (*Process) HandleEvent

func (p *Process) HandleEvent(ctx context.Context, eventID string, eventName string, payload any, callContext ExtensionCallContext) (*EventResult, error)

HandleEvent invokes an extension event handler.

func (*Process) HandleRPCRequest

func (p *Process) HandleRPCRequest(ctx context.Context, method string, params json.RawMessage) (any, *rpcError)

func (*Process) Initialize

func (p *Process) Initialize(ctx context.Context, cwd string) (*InitializeResult, error)

Initialize initializes the extension process and returns its registrations.

type Root

type Root struct {
	Dir          string
	Kind         SourceKind
	PluginPrefix string
}

Root describes a directory that should be scanned for extension executables.

type RoutedCommandResult

type RoutedCommandResult struct {
	Matched      bool
	CommandName  string
	ExtensionID  string
	Action       string
	Response     string
	Prompt       string
	RecipeName   string
	Display      string
	Registration CommandRegistration
}

RoutedCommandResult is returned by TryCommand.

type Runtime

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

Runtime manages discovered extension processes and registrations.

func EmptyRuntime

func EmptyRuntime() *Runtime

EmptyRuntime creates an extension runtime with no processes or registrations. It is useful for callers that want to attach a non-nil runtime before discovery has found any extensions.

func NewRuntime

func NewRuntime(ctx context.Context, opts ...DiscoveryOption) (*Runtime, error)

NewRuntime creates and initializes an extension runtime.

func NewRuntimeFromViper

func NewRuntimeFromViper(ctx context.Context, workingDir string) (*Runtime, error)

NewRuntimeFromViper creates a runtime from viper config.

func (*Runtime) Close

func (r *Runtime) Close() error

Close terminates all extension processes.

func (*Runtime) Commands

func (r *Runtime) Commands() []Command

Commands returns registered extension commands.

func (*Runtime) DispatchAgentEnd

func (r *Runtime) DispatchAgentEnd(ctx context.Context, callContext ExtensionCallContext, messages []llmtypes.Message) []string

DispatchAgentEnd runs agent.end subscriptions and returns accumulated follow-up messages.

func (*Runtime) DispatchAgentInit

func (r *Runtime) DispatchAgentInit(ctx context.Context, callContext ExtensionCallContext, systemPrompt string) string

DispatchAgentInit runs agent.init subscriptions and applies system prompt patches.

func (*Runtime) DispatchAgentInitDecision

func (r *Runtime) DispatchAgentInitDecision(ctx context.Context, callContext ExtensionCallContext, systemPrompt string, allowedTools []string) AgentInitDecision

DispatchAgentInitDecision runs agent.init subscriptions and applies system prompt and tool-list patches.

func (*Runtime) DispatchAgentStart

func (r *Runtime) DispatchAgentStart(ctx context.Context, callContext ExtensionCallContext)

DispatchAgentStart runs agent.start subscriptions.

func (*Runtime) DispatchResourcesDiscover

func (r *Runtime) DispatchResourcesDiscover(ctx context.Context, callContext ExtensionCallContext)

DispatchResourcesDiscover runs resources.discover subscriptions.

func (*Runtime) DispatchSessionEnd

func (r *Runtime) DispatchSessionEnd(ctx context.Context, callContext ExtensionCallContext)

DispatchSessionEnd runs session.end subscriptions.

func (*Runtime) DispatchSessionStart

func (r *Runtime) DispatchSessionStart(ctx context.Context, callContext ExtensionCallContext)

DispatchSessionStart runs session.start subscriptions.

func (*Runtime) DispatchToolCall

func (r *Runtime) DispatchToolCall(ctx context.Context, callContext ExtensionCallContext, toolName, toolInput, toolCallID string) ToolCallDecision

DispatchToolCall runs tool.call subscriptions sequentially.

func (*Runtime) DispatchToolResult

func (r *Runtime) DispatchToolResult(ctx context.Context, callContext ExtensionCallContext, toolName, toolInput, toolCallID string, output tooltypes.StructuredToolResult) (tooltypes.StructuredToolResult, bool)

DispatchToolResult runs tool.result subscriptions sequentially.

func (*Runtime) DispatchTurnEnd

func (r *Runtime) DispatchTurnEnd(ctx context.Context, callContext ExtensionCallContext, response string, turnNumber int)

DispatchTurnEnd runs turn.end subscriptions.

func (*Runtime) DispatchTurnStart

func (r *Runtime) DispatchTurnStart(ctx context.Context, callContext ExtensionCallContext, turnNumber int)

DispatchTurnStart runs turn.start subscriptions.

func (*Runtime) DispatchUserMessage

func (r *Runtime) DispatchUserMessage(ctx context.Context, callContext ExtensionCallContext, message string) UserMessageDecision

DispatchUserMessage runs user.message subscriptions sequentially.

func (*Runtime) SlashCommands

func (r *Runtime) SlashCommands() []slashcommands.Command

SlashCommands returns extension command registrations in the shared slash command shape used by CLI/ACP/web command discovery surfaces.

func (*Runtime) Subscriptions

func (r *Runtime) Subscriptions() []Subscription

Subscriptions returns registered extension event subscriptions.

func (*Runtime) Tools

func (r *Runtime) Tools() []tooltypes.Tool

Tools returns registered extension tools sorted by name.

func (*Runtime) TryCommand

func (r *Runtime) TryCommand(ctx context.Context, rawPrompt, commandName, args string, callContext ExtensionCallContext) (*RoutedCommandResult, error)

TryCommand routes a parsed slash command through extension command registrations.

type SourceKind

type SourceKind string

SourceKind identifies where an extension was discovered.

const (
	SourceKindLocalStandalone  SourceKind = "local_standalone"
	SourceKindLocalPlugin      SourceKind = "local_plugin"
	SourceKindGlobalStandalone SourceKind = "global_standalone"
	SourceKindGlobalPlugin     SourceKind = "global_plugin"
)

type Subscription

type Subscription struct {
	Event        string   `json:"event"`
	Priority     int      `json:"priority,omitempty"`
	TimeoutInSec *float64 `json:"timeoutInSec,omitempty"`
}

Subscription declares an event handler registered by an extension.

type SystemPromptPatch

type SystemPromptPatch struct {
	Prepend *string `json:"prepend,omitempty"`
	Append  *string `json:"append,omitempty"`
	Replace *string `json:"replace,omitempty"`
}

SystemPromptPatch describes an agent.init system prompt mutation.

type TerminalUIInputBroker

type TerminalUIInputBroker struct {
	In          io.Reader
	Out         io.Writer
	Interactive bool
	// contains filtered or unexported fields
}

TerminalUIInputBroker prompts for extension-requested input in an interactive terminal.

func NewTerminalUIInputBroker

func NewTerminalUIInputBroker(in io.Reader, out io.Writer) *TerminalUIInputBroker

NewTerminalUIInputBroker creates a terminal-backed UI input broker.

func (*TerminalUIInputBroker) Confirm

Confirm asks the user for a yes/no decision.

func (*TerminalUIInputBroker) Input

Input asks the user for a single line of input.

func (*TerminalUIInputBroker) Notify

Notify displays a one-way notification.

func (*TerminalUIInputBroker) Select

Select asks the user to choose one option.

type Tool

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

Tool is a tool registered by an extension.

func (*Tool) Description

func (t *Tool) Description() string

Description returns the extension tool description.

func (*Tool) Execute

func (t *Tool) Execute(ctx context.Context, _ tooltypes.State, parameters string) tooltypes.ToolResult

Execute invokes the extension tool over JSON-RPC.

func (*Tool) GenerateSchema

func (t *Tool) GenerateSchema() *jsonschema.Schema

GenerateSchema returns a typed compatibility view of the extension schema.

func (*Tool) Name

func (t *Tool) Name() string

Name returns the extension tool name.

func (*Tool) RawInputSchema

func (t *Tool) RawInputSchema() map[string]any

RawInputSchema returns the extension-provided schema without narrowing it.

func (*Tool) TracingKVs

func (t *Tool) TracingKVs(_ string) ([]attribute.KeyValue, error)

TracingKVs returns tracing attributes for the tool.

func (*Tool) ValidateInput

func (t *Tool) ValidateInput(_ tooltypes.State, parameters string) error

ValidateInput validates JSON syntax. Schema validation is delegated to the extension SDK/runtime.

type ToolCallDecision

type ToolCallDecision struct {
	Blocked bool
	Reason  string
	Input   string
}

ToolCallDecision is the result of dispatching a tool.call event.

type ToolConfig

type ToolConfig struct {
	Enabled *bool `mapstructure:"enabled" json:"enabled" yaml:"enabled"`
}

ToolConfig controls runtime behavior for a specific extension-provided tool.

type ToolExecutionResult

type ToolExecutionResult struct {
	Content string         `json:"content"`
	Data    map[string]any `json:"data,omitempty"`
	Error   string         `json:"error,omitempty"`
}

ToolExecutionResult is returned by extension.tool.execute.

type ToolListPatch

type ToolListPatch struct {
	Disable []string `json:"disable,omitempty"`
	Enable  []string `json:"enable,omitempty"`
}

ToolListPatch describes an agent.init mutation to the tool allowlist.

type ToolRegistration

type ToolRegistration struct {
	Name         string         `json:"name"`
	Description  string         `json:"description"`
	InputSchema  map[string]any `json:"inputSchema"`
	TimeoutInSec *float64       `json:"timeoutInSec,omitempty"`
}

ToolRegistration is returned by an extension during initialization.

type ToolResult

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

ToolResult is the result of an extension tool execution.

func (*ToolResult) AssistantFacing

func (r *ToolResult) AssistantFacing() string

AssistantFacing returns the result for the assistant.

func (*ToolResult) GetError

func (r *ToolResult) GetError() string

GetError returns the error string.

func (*ToolResult) GetResult

func (r *ToolResult) GetResult() string

GetResult returns the result string.

func (*ToolResult) IsError

func (r *ToolResult) IsError() bool

IsError returns true when execution failed.

func (*ToolResult) String

func (r *ToolResult) String() string

func (*ToolResult) StructuredData

func (r *ToolResult) StructuredData() tooltypes.StructuredToolResult

StructuredData returns structured metadata.

type UIConfirmBroker

type UIConfirmBroker interface {
	Confirm(ctx context.Context, request UIConfirmRequest) (UIInputResponse, error)
}

UIConfirmBroker routes extension confirmation requests to the active user interface.

func UIConfirmBrokerFromContext

func UIConfirmBrokerFromContext(ctx context.Context) (UIConfirmBroker, bool)

UIConfirmBrokerFromContext returns the run-scoped confirmation broker, if one exists.

type UIConfirmRequest

type UIConfirmRequest struct {
	ID                string `json:"id,omitempty"`
	Title             string `json:"title"`
	Message           string `json:"message,omitempty"`
	ConfirmButtonText string `json:"confirmButtonText,omitempty"`
	CancelButtonText  string `json:"cancelButtonText,omitempty"`
}

UIConfirmRequest describes a yes/no prompt requested by an extension.

type UIInputBroker

type UIInputBroker interface {
	Input(ctx context.Context, request UIInputRequest) (UIInputResponse, error)
}

UIInputBroker routes extension UI input requests to the active user interface.

func UIInputBrokerFromContext

func UIInputBrokerFromContext(ctx context.Context) (UIInputBroker, bool)

UIInputBrokerFromContext returns the run-scoped UI input broker, if one exists.

type UIInputRequest

type UIInputRequest struct {
	ID               string `json:"id,omitempty"`
	Title            string `json:"title"`
	HelpText         string `json:"helpText,omitempty"`
	Message          string `json:"message,omitempty"`
	Placeholder      string `json:"placeholder,omitempty"`
	DefaultValue     string `json:"defaultValue,omitempty"`
	SubmitButtonText string `json:"submitButtonText,omitempty"`
	CancelButtonText string `json:"cancelButtonText,omitempty"`
	Required         bool   `json:"required,omitempty"`
	Secret           bool   `json:"secret,omitempty"`
}

UIInputRequest describes a user-input prompt requested by an extension.

type UIInputResponse

type UIInputResponse struct {
	Status    string `json:"status"`
	Value     string `json:"value,omitempty"`
	Confirmed bool   `json:"confirmed,omitempty"`
	Reason    string `json:"reason,omitempty"`
}

UIInputResponse is returned to the extension after a UI input prompt resolves.

type UINotifyBroker

type UINotifyBroker interface {
	Notify(ctx context.Context, request UINotifyRequest) (UIInputResponse, error)
}

UINotifyBroker routes extension notifications to the active user interface.

func UINotifyBrokerFromContext

func UINotifyBrokerFromContext(ctx context.Context) (UINotifyBroker, bool)

UINotifyBrokerFromContext returns the run-scoped notification broker, if one exists.

type UINotifyRequest

type UINotifyRequest struct {
	Title   string `json:"title,omitempty"`
	Message string `json:"message"`
}

UINotifyRequest describes a fire-and-forget notification requested by an extension.

type UISelectBroker

type UISelectBroker interface {
	Select(ctx context.Context, request UISelectRequest) (UIInputResponse, error)
}

UISelectBroker routes extension selection requests to the active user interface.

func UISelectBrokerFromContext

func UISelectBrokerFromContext(ctx context.Context) (UISelectBroker, bool)

UISelectBrokerFromContext returns the run-scoped selection broker, if one exists.

type UISelectRequest

type UISelectRequest struct {
	ID               string   `json:"id,omitempty"`
	Title            string   `json:"title"`
	Message          string   `json:"message,omitempty"`
	Options          []string `json:"options"`
	SubmitButtonText string   `json:"submitButtonText,omitempty"`
	CancelButtonText string   `json:"cancelButtonText,omitempty"`
}

UISelectRequest describes a single-choice prompt requested by an extension.

type UserMessageDecision

type UserMessageDecision struct {
	Blocked bool
	Reason  string
	Message string
}

UserMessageDecision is the result of dispatching a user.message event.

Jump to

Keyboard shortcuts

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