forgeui

package module
v0.0.0-...-b59f3eb Latest Latest
Warning

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

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

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SkillBuilderCodegenModel deprecated

func SkillBuilderCodegenModel(_, configured string) string

SkillBuilderCodegenModel previously hardcoded "gpt-4.1" / "claude-opus-4-6" regardless of the agent's configured model. Issue #92 removed that override: the skill builder now uses the operator-chosen model from workspace-level ui.yaml (see uiconfig.LoadSkillBuilderLLM). The function is retained as a no-op shim with a deprecation marker so any out-of-tree callers fail loudly.

Deprecated: skill-builder model selection is now driven by uiconfig.

Types

type AgentCreateFunc

type AgentCreateFunc func(opts AgentCreateOptions) (agentDir string, err error)

AgentCreateFunc scaffolds a new agent in the workspace. Injected by forge-cli.

type AgentCreateOptions

type AgentCreateOptions struct {
	Name              string             `json:"name"`
	Framework         string             `json:"framework"`
	ModelProvider     string             `json:"model_provider"`
	ModelName         string             `json:"model_name,omitempty"`
	APIKey            string             `json:"api_key,omitempty"`
	AuthMethod        string             `json:"auth_method,omitempty"` // "apikey" or "oauth"
	OrganizationID    string             `json:"organization_id,omitempty"`
	AWSRegion         string             `json:"aws_region,omitempty"` // required for model_provider "bedrock" (#205)
	Channels          []string           `json:"channels,omitempty"`
	BuiltinTools      []string           `json:"builtin_tools,omitempty"`
	Skills            []string           `json:"skills,omitempty"`
	Fallbacks         []FallbackProvider `json:"fallbacks,omitempty"`
	WebSearchProvider string             `json:"web_search_provider,omitempty"` // "tavily" or "perplexity"
	Passphrase        string             `json:"passphrase,omitempty"`
	EnvVars           map[string]string  `json:"env_vars,omitempty"`
	Force             bool               `json:"force,omitempty"`
	Auth              *AuthCreateOptions `json:"auth,omitempty"` // A2A server auth chain (PR6+)
}

AgentCreateOptions contains all parameters for creating a new agent.

type AgentInfo

type AgentInfo struct {
	ID        string     `json:"id"`
	Version   string     `json:"version"`
	Framework string     `json:"framework"`
	Model     AgentModel `json:"model"`
	Tools     []string   `json:"tools"`
	Channels  []string   `json:"channels"`
	// DeniedChannels is the channel deny set after resolving
	// system / user / workspace policy layers. The agent card uses
	// this to render denied channels with a visual disabled state.
	// Toggling a chip mutates the user policy file via
	// PUT /api/user-policy, NOT this list directly. See issue #90 /
	// FWS-6 (three-layer policy resolution).
	DeniedChannels  []string     `json:"denied_channels,omitempty"`
	Skills          int          `json:"skills"`
	Directory       string       `json:"directory"`
	Status          ProcessState `json:"status"`
	Port            int          `json:"port,omitempty"`
	Error           string       `json:"error,omitempty"`
	StartedAt       *time.Time   `json:"started_at,omitempty"`
	NeedsPassphrase bool         `json:"needs_passphrase,omitempty"`
}

AgentInfo describes a discovered agent and its runtime state.

type AgentModel

type AgentModel struct {
	Provider string `json:"provider"`
	Name     string `json:"name"`
}

AgentModel holds model provider and name.

type AuthCreateOptions

type AuthCreateOptions struct {
	Mode     string         `json:"mode"`
	Settings map[string]any `json:"settings,omitempty"`
}

AuthCreateOptions describes the auth chain selection the web wizard captured. Mode is one of "none", "oidc", "http_verifier", "custom". Settings is the provider-type-specific settings block (issuer, audience, url, default_org, claim_map, …). Mirrors the TUI wizard's contract so both surfaces feed the same scaffold path.

type AuthProviderTypeMeta

type AuthProviderTypeMeta struct {
	Type        string `json:"type"`        // "none", "oidc", "http_verifier", "custom"
	Label       string `json:"label"`       // human-readable label for the picker
	Description string `json:"description"` // single-line description under the label
}

AuthProviderTypeMeta describes one selectable auth provider type so the frontend renders its picker from server-driven metadata (no hardcoded provider list in JavaScript). When a new provider ships (e.g., Okta in Phase 3), append one entry here and the wizard picks it up.

type BuiltinToolInfo

type BuiltinToolInfo struct {
	Name        string `json:"name"`
	Description string `json:"description"`
}

BuiltinToolInfo describes a builtin tool for the wizard.

type ChatRequest

type ChatRequest struct {
	Message   string `json:"message"`
	SessionID string `json:"session_id,omitempty"`
}

ChatRequest is the POST body for the chat endpoint.

type ConfigUpdateRequest

type ConfigUpdateRequest struct {
	Content string `json:"content"`
}

ConfigUpdateRequest is the PUT body for saving forge.yaml.

type ConfigValidateResponse

type ConfigValidateResponse struct {
	Valid    bool     `json:"valid"`
	Errors   []string `json:"errors,omitempty"`
	Warnings []string `json:"warnings,omitempty"`
}

ConfigValidateResponse returned from validate/save endpoints.

type CreateAgentResponse

type CreateAgentResponse struct {
	AgentID   string `json:"agent_id"`
	Directory string `json:"directory"`
	Message   string `json:"message"`
}

CreateAgentResponse is returned after successful agent creation.

type CustomSkillContent

type CustomSkillContent struct {
	Name    string            `json:"name"`
	SkillMD string            `json:"skill_md"`
	Scripts map[string]string `json:"scripts,omitempty"`
	Path    string            `json:"path"`
	Format  string            `json:"format"`
}

CustomSkillContent is the full payload for one custom skill — its SKILL.md body plus any helper scripts under skills/<name>/scripts/. Used by the Skill Builder edit flow to populate the editor (issue #193).

Format is "subdir" when the skill lives at skills/<name>/SKILL.md (the common case, where helper scripts live next to it), or "flat" when it's a single-file skills/<name>.md (no scripts directory).

type CustomSkillSummary

type CustomSkillSummary struct {
	Name        string   `json:"name"`
	Description string   `json:"description"`
	Category    string   `json:"category,omitempty"`
	Tags        []string `json:"tags,omitempty"`
	Path        string   `json:"path"`
	HasScripts  bool     `json:"has_scripts"`
	Tools       []string `json:"tools,omitempty"`
}

CustomSkillSummary describes one project-local skill discovered under the agent's skills/ directory (issue #193). Distinct from SkillBrowserEntry, which describes registry/embedded skills the user can add to a new agent — this type only covers skills already attached to the agent on disk.

type FallbackProvider

type FallbackProvider struct {
	Provider string `json:"provider"`
	APIKey   string `json:"api_key,omitempty"`
}

FallbackProvider describes a fallback LLM provider with its API key.

type LLMStreamFunc

type LLMStreamFunc func(ctx context.Context, opts LLMStreamOptions) error

LLMStreamFunc streams an LLM response for the skill builder. Injected by forge-cli.

type LLMStreamOptions

type LLMStreamOptions struct {
	LLM          uiconfig.SkillBuilderLLM
	AgentDir     string
	SystemPrompt string
	Messages     []SkillBuilderMessage
	OnChunk      func(string)
	OnDone       func(fullResponse string)
}

LLMStreamOptions configures a streaming LLM call for the skill builder.

The LLM struct is the resolved skill-builder LLM configuration — workspace-level (per issue #92) when available, with the agent- fallback path used only when no workspace/user config exists. Callers in forge-cli MUST consume LLM directly rather than re-reading the agent's forge.yaml / .env: doing so would re-introduce the per-agent env-stomping the workspace-LLM design replaced.

AgentDir is retained for the deprecated fallback resolution path only — forge-ui passes it so the loader can read the agent's forge.yaml when no workspace/user config exists. New code paths should not depend on it.

type ModelOption

type ModelOption struct {
	DisplayName string `json:"display_name"`
	ModelID     string `json:"model_id"`
}

ModelOption maps a display name to the actual model ID.

type OAuthFlowFunc

type OAuthFlowFunc func(provider string) (accessToken string, err error)

OAuthFlowFunc runs the OAuth browser flow for a provider and returns the access token. Injected by forge-cli when OAuth is available.

type PortAllocator

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

PortAllocator manages port assignment for agent processes.

func NewPortAllocator

func NewPortAllocator(basePort int) *PortAllocator

NewPortAllocator creates a PortAllocator starting from basePort.

func (*PortAllocator) Allocate

func (pa *PortAllocator) Allocate() int

Allocate returns the next available port. It verifies the port is actually free (not just absent from the used map) by attempting a TCP listen. This prevents collisions with externally-started agents or other processes that the PortAllocator doesn't know about (e.g., after a UI restart).

func (*PortAllocator) Release

func (pa *PortAllocator) Release(port int)

Release frees a port for reuse.

type ProcessManager

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

ProcessManager manages agent process lifecycles via `forge serve` commands.

func NewProcessManager

func NewProcessManager(exePath string, broker *SSEBroker, basePort int) *ProcessManager

NewProcessManager creates a ProcessManager.

func (*ProcessManager) Start

func (pm *ProcessManager) Start(agentID string, info *AgentInfo, passphrase string) error

Start launches an agent via `forge serve start`.

func (*ProcessManager) Stop

func (pm *ProcessManager) Stop(agentID string, info *AgentInfo) error

Stop stops an agent via `forge serve stop`.

Takes the full *AgentInfo so every broadcast carries a complete record: fields without omitempty marshal as zero values, and the dashboard merges events by object spread, so a stub event blanks the card's metadata.

func (*ProcessManager) StopAll

func (pm *ProcessManager) StopAll()

StopAll is a no-op — agents intentionally survive UI shutdown.

type ProcessState

type ProcessState string

ProcessState represents the lifecycle state of an agent process.

const (
	StateStopped  ProcessState = "stopped"
	StateStarting ProcessState = "starting"
	StateRunning  ProcessState = "running"
	StateStopping ProcessState = "stopping"
	StateErrored  ProcessState = "errored"
)

type ProviderModels

type ProviderModels struct {
	Default       string        `json:"default"`
	APIKey        []ModelOption `json:"api_key,omitempty"`
	OAuth         []ModelOption `json:"oauth,omitempty"`
	HasOAuth      bool          `json:"has_oauth,omitempty"`
	NeedsKey      bool          `json:"needs_key"`
	IsCustom      bool          `json:"is_custom,omitempty"`
	BaseURLEnv    string        `json:"base_url_env,omitempty"` // e.g. "OPENAI_BASE_URL"
	SupportsOrgID bool          `json:"supports_org_id,omitempty"`
	// NeedsAWSRegion prompts the wizard for an AWS region (submitted as
	// aws_region) instead of an API key — provider "bedrock" signs with
	// SigV4 from AWS env credentials. Issue #205.
	NeedsAWSRegion bool `json:"needs_aws_region,omitempty"`
}

ProviderModels holds model lists for a specific provider.

type SSEBroker

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

SSEBroker manages fan-out of SSE events to multiple subscribers.

func NewSSEBroker

func NewSSEBroker() *SSEBroker

NewSSEBroker creates a new SSEBroker.

func (*SSEBroker) Broadcast

func (b *SSEBroker) Broadcast(event SSEEvent)

Broadcast sends an event to all subscribers. Non-blocking: slow subscribers that have a full buffer will have the event dropped.

func (*SSEBroker) Subscribe

func (b *SSEBroker) Subscribe() chan SSEEvent

Subscribe registers a new client and returns a channel for receiving events.

func (*SSEBroker) Unsubscribe

func (b *SSEBroker) Unsubscribe(ch chan SSEEvent)

Unsubscribe removes a client and closes its channel.

type SSEEvent

type SSEEvent struct {
	Type string `json:"type"`
	Data any    `json:"data"`
}

SSEEvent is an event broadcast to connected UI clients.

type Scanner

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

Scanner discovers agents in a workspace directory.

func NewScanner

func NewScanner(rootDir string) *Scanner

NewScanner creates a Scanner for the given workspace root.

func (*Scanner) Scan

func (s *Scanner) Scan() (map[string]*AgentInfo, error)

Scan discovers agents by looking for forge.yaml in the root directory and each immediate subdirectory. Returns a map keyed by agent ID.

type SessionInfo

type SessionInfo struct {
	ID        string    `json:"id"`
	Preview   string    `json:"preview"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

SessionInfo describes a stored chat session for listing.

type SkillBrowserEntry

type SkillBrowserEntry struct {
	Name          string   `json:"name"`
	DisplayName   string   `json:"display_name"`
	Description   string   `json:"description"`
	Category      string   `json:"category"`
	Tags          []string `json:"tags"`
	RequiredEnv   []string `json:"required_env,omitempty"`
	OneOfEnv      []string `json:"one_of_env,omitempty"`
	OptionalEnv   []string `json:"optional_env,omitempty"`
	RequiredBins  []string `json:"required_bins,omitempty"`
	EgressDomains []string `json:"egress_domains,omitempty"`
}

SkillBrowserEntry describes a registry skill for the API.

type SkillBuilderChatRequest

type SkillBuilderChatRequest struct {
	Messages    []SkillBuilderMessage `json:"messages"`
	Mode        string                `json:"mode,omitempty"`
	EditingName string                `json:"editing_name,omitempty"`
}

SkillBuilderChatRequest is the POST body for the skill builder chat endpoint.

Mode selects between "create" (default) and "edit". In edit mode the handler loads the skill named by EditingName from disk and primes the system prompt with its current SKILL.md + scripts so the LLM is grounded on the existing state. See issue #193.

type SkillBuilderMessage

type SkillBuilderMessage struct {
	Role    string `json:"role"`
	Content string `json:"content"`
}

SkillBuilderMessage is a chat message for the skill builder conversation.

type SkillBuilderSaveRequest

type SkillBuilderSaveRequest struct {
	SkillName   string            `json:"skill_name"`
	SkillMD     string            `json:"skill_md"`
	Scripts     map[string]string `json:"scripts,omitempty"`
	EnvVars     map[string]string `json:"env_vars,omitempty"`
	Overwrite   bool              `json:"overwrite,omitempty"`
	EditingName string            `json:"editing_name,omitempty"`
}

SkillBuilderSaveRequest is the POST body for saving a skill.

Overwrite=true with EditingName matching SkillName allows rewriting the existing skill directory in place (issue #193 — edit-mode iteration). Stale scripts in the existing scripts/ dir are removed before the new set is written so dropped scripts don't linger. Overwriting any OTHER skill's directory is denied as defense in depth.

type SkillBuilderValidateRequest

type SkillBuilderValidateRequest struct {
	SkillMD     string            `json:"skill_md"`
	Scripts     map[string]string `json:"scripts,omitempty"`
	Mode        string            `json:"mode,omitempty"`
	EditingName string            `json:"editing_name,omitempty"`
}

SkillBuilderValidateRequest is the POST body for skill validation.

When Mode == "edit" and EditingName matches the skill name in the frontmatter, the "already exists" warning is suppressed — the skill IS the one being edited. A rename (EditingName != frontmatter name) still surfaces the warning so the user sees the breaking-change risk.

type SkillEnvEntry

type SkillEnvEntry struct {
	Name string `json:"name"`
	Kind string `json:"kind"` // "required", "one_of", "optional"
}

SkillEnvEntry describes a missing environment variable requirement.

type SkillSaveFunc

type SkillSaveFunc func(opts SkillSaveOptions) (*SkillSaveResult, error)

SkillSaveFunc saves a generated skill to disk and configures env/egress. Injected by forge-cli.

type SkillSaveOptions

type SkillSaveOptions struct {
	AgentDir    string
	SkillName   string
	SkillMD     string
	Scripts     map[string]string
	EnvVars     map[string]string // env vars to write to .env
	Overwrite   bool
	EditingName string
}

SkillSaveOptions configures saving a skill to an agent's skills directory.

Overwrite=true with EditingName matching SkillName is the edit-mode path (issue #193). The forge-cli implementation MUST honor this: on overwrite it should remove the existing scripts/ directory before writing the new script set, so scripts dropped during the edit don't linger. Overwrite without an EditingName match — i.e. trying to overwrite a different skill — is rejected by the handler before the SkillSaveFunc is called.

type SkillSaveResult

type SkillSaveResult struct {
	Path          string          `json:"path"`
	EgressAdded   []string        `json:"egress_added,omitempty"`
	EnvConfigured []string        `json:"env_configured,omitempty"`
	EnvMissing    []SkillEnvEntry `json:"env_missing,omitempty"`
}

SkillSaveResult holds the result of saving a skill, including env/egress changes.

type SkillValidationResult

type SkillValidationResult struct {
	Valid    bool              `json:"valid"`
	Errors   []ValidationError `json:"errors,omitempty"`
	Warnings []ValidationError `json:"warnings,omitempty"`
}

SkillValidationResult holds the result of validating a SKILL.md.

type StartRequest

type StartRequest struct {
	Passphrase string `json:"passphrase,omitempty"`
}

StartRequest is the optional POST body for the start endpoint.

type UIServer

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

UIServer serves the Forge dashboard UI and API.

func NewUIServer

func NewUIServer(cfg UIServerConfig) *UIServer

NewUIServer creates a UIServer with the given configuration.

func (*UIServer) Start

func (s *UIServer) Start(ctx context.Context) error

Start starts the server and blocks until ctx is cancelled.

type UIServerConfig

type UIServerConfig struct {
	Port          int             // default: 4200
	WorkDir       string          // workspace root to scan for agents
	ExePath       string          // path to forge binary for exec
	Version       string          // forge version string
	CreateFunc    AgentCreateFunc // injected by forge-cli (Phase 3)
	OAuthFunc     OAuthFlowFunc   // injected by forge-cli (optional, for OAuth login)
	LLMStreamFunc LLMStreamFunc   // injected by forge-cli (skill builder)
	SkillSaveFunc SkillSaveFunc   // injected by forge-cli (skill builder)
	AgentPort     int             // base port for agent allocation (default: 9100)
	OpenBrowser   bool            // open browser on start
}

UIServerConfig configures the UI dashboard server.

type ValidationError

type ValidationError struct {
	Field   string `json:"field"`
	Message string `json:"message"`
}

ValidationError describes a single validation issue.

type WebSearchProviderOption

type WebSearchProviderOption struct {
	Name        string `json:"name"`
	Label       string `json:"label"`
	Description string `json:"description"`
	EnvVar      string `json:"env_var"`
	Placeholder string `json:"placeholder"`
}

WebSearchProviderOption describes a web search provider.

type WizardMetadata

type WizardMetadata struct {
	Providers          []string                  `json:"providers"`
	Frameworks         []string                  `json:"frameworks"`
	Channels           []string                  `json:"channels"`
	BuiltinTools       []BuiltinToolInfo         `json:"builtin_tools"`
	Skills             []SkillBrowserEntry       `json:"skills"`
	ProviderModels     map[string]ProviderModels `json:"provider_models"`
	WebSearchProviders []WebSearchProviderOption `json:"web_search_providers"`
	AuthProviderTypes  []AuthProviderTypeMeta    `json:"auth_provider_types"`
}

WizardMetadata holds all reference data the frontend wizard needs.

Directories

Path Synopsis
Package uiconfig holds the workspace-level configuration that the forge ui process consumes — independent of any specific agent's forge.yaml.
Package uiconfig holds the workspace-level configuration that the forge ui process consumes — independent of any specific agent's forge.yaml.

Jump to

Keyboard shortcuts

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