api

package
v1.0.8 Latest Latest
Warning

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

Go to latest
Published: Dec 10, 2025 License: MIT Imports: 26 Imported by: 0

Documentation

Index

Constants

View Source
const FlowSchema = `
# Astonish Agent Flow Schema

## Overview
An agent flow is defined in YAML with nodes (processing steps) and flow (edges connecting them).

## Basic Structure
` + "```yaml" + `
name: agent_name
description: What this agent does
model: gemini-2.0-flash  # or gpt-4o, claude-3-5-sonnet, etc.

nodes:
  - name: node_name
    type: llm|input|tool|output|update_state
    # type-specific fields...

flow:
  - from: START
    to: first_node
  - from: first_node
    to: second_node
  - from: last_node
    to: END
` + "```" + `

## Node Types

### 1. LLM Node (PREFERRED for tool usage)
AI processing with optional tool use.
- output_model: saves result to state for later nodes
- user_message: DISPLAY result to user (use this when user needs to see the response!)
` + "```yaml" + `
# LLM that shows answer to user (most common pattern)
- name: answer_question
  type: llm
  system: "You are a helpful assistant."
  prompt: "{user_question}"
  output_model:
    answer: str
  user_message:
    - answer  # This displays the LLM response to the user!

# LLM with tools
- name: search_and_summarize
  type: llm
  system: "You are a search assistant."
  prompt: "Search for: {query}"
  tools: true
  tools_selection:
    - tavily-search
  output_model:
    search_result: str
  user_message:
    - search_result  # Show the result to user
` + "```" + `

### 2. Input Node
Collect user input. output_model is REQUIRED to store input in state.

**IMPORTANT: options behavior**
- WITHOUT options: User can type ANY text (free form input)
- WITH options: User can ONLY select from the listed options (no free text!)
` + "```yaml" + `
# Free text input - user can type anything
- name: get_question
  type: input
  prompt: "What is your question?"
  output_model:
    question: str

# Choice input - user can ONLY select from these options
- name: ask_continue
  type: input
  prompt: "Continue? (yes/no)"
  output_model:
    choice: str
  options:
    - "yes"
    - "no"
` + "```" + `
**DO NOT use options if you want the user to type free text!**

### 3. Tool Node (RARELY USED)
Execute a tool directly WITHOUT LLM intelligence. Only use when you need deterministic tool execution.
In most cases, prefer LLM node with tools: true instead.
` + "```yaml" + `
- name: run_fixed_command
  type: tool
  tools_selection:
    - shell_command
  args:
    command: "ls -la"
  output_model:
    shell_result: str
` + "```" + `

### 4. Output Node
Display messages to user. Use user_message array with strings and state variable names.
Note: LLM responses are shown automatically, so output nodes are mainly for formatting/labeling.
` + "```yaml" + `
- name: show_result
  type: output
  user_message:
    - "Answer:"
    - answer
` + "```" + `

### 5. Update State Node
Modify state variables. Use source_variable OR value to set data, action to control how (overwrite/append), 
and output_model to define the target variable and its type.
` + "```yaml" + `
# Overwrite a variable with a value
- name: set_flag
  type: update_state
  value: "true"
  action: overwrite
  output_model:
    is_processed: string

# Copy from one variable to another
- name: save_result
  type: update_state
  source_variable: llm_response
  action: overwrite
  output_model:
    saved_answer: string

# Append to a list
- name: add_to_history
  type: update_state
  source_variable: current_item
  action: append
  output_model:
    history_list: list
` + "```" + `

## Flow Edges

### Simple Edge
` + "```yaml" + `
- from: node_a
  to: node_b
` + "```" + `

### Conditional Edges
` + "```yaml" + `
- from: decision_node
  edges:
    - to: yes_path
      condition: "lambda x: x['decision'] == 'yes'"
    - to: no_path
      condition: "lambda x: x['decision'] == 'no'"
` + "```" + `

### Loop (Back-edge)
IMPORTANT: Loops must point to actual nodes, NEVER to START!
` + "```yaml" + `
- from: ask_continue
  edges:
    - to: get_question  # Loop back to the actual node, NOT to START!
      condition: "lambda x: x['continue'] == 'yes'"
    - to: END
      condition: "lambda x: x['continue'] == 'no'"
` + "```" + `

## State & Templating
- Use {variable_name} to reference state (single braces, no spaces)
- Data flows through nodes via output_model which saves to state
- Access previous node outputs from state keys defined in output_model

## Patterns

### User Confirmation Pattern
Use INPUT node with options for reliable branching:
` + "```yaml" + `
- name: confirm
  type: input
  prompt: "Continue? (yes/no)"
  output_model:
    choice: str
  options:
    - "yes"
    - "no"
` + "```" + `
Then use in conditional edge: ` + "`" + `condition: "lambda x: x['choice'] == 'yes'"` + "`" + `

### Displaying LLM Response
Always add user_message when the user should see the output:
` + "```yaml" + `
- name: process
  type: llm
  prompt: "{user_input}"
  output_model:
    result: str
  user_message:
    - result  # This shows the response to the user
` + "```" + `

## Anti-Patterns (DO NOT DO)

❌ Using LLM to check yes/no conditions - unpredictable output breaks edges
❌ Creating "check_exit" or "check_quit" nodes - use input with options instead  
❌ Missing user_message on LLM nodes - user won't see the response
❌ Using LLM output in conditional edges - conditions may never match

## Rules
1. Flow must start from START and end at END
2. START and END are VIRTUAL nodes - they are NOT actual nodes you define
3. You can ONLY use "from: START" to begin the flow - NEVER use "to: START"
4. Loops must point to actual node names (e.g., "to: get_question"), NEVER to START
5. All node names must be unique
6. Use output_model to pass data between nodes
7. ALWAYS include user_message on LLM nodes when user should see output
8. For branching/loops, use INPUT with options - gives reliable condition values
9. NEVER use LLM output in conditional edges - it's unpredictable
`

FlowSchema contains the schema documentation for AI to understand flow structure

Variables

This section is empty.

Functions

func AIChatHandler

func AIChatHandler(w http.ResponseWriter, r *http.Request)

AIChatHandler handles AI chat requests

func DeleteAgentHandler

func DeleteAgentHandler(w http.ResponseWriter, r *http.Request)

DeleteAgentHandler handles DELETE /api/agents/{name}

func FormatValidationErrors

func FormatValidationErrors(errors []string) string

FormatValidationErrors formats validation errors for LLM feedback

func GetAgentHandler

func GetAgentHandler(w http.ResponseWriter, r *http.Request)

GetAgentHandler handles GET /api/agents/{name}

func GetFlowSchema

func GetFlowSchema() string

GetFlowSchema returns the schema as a string for AI context

func GetMCPSettingsHandler

func GetMCPSettingsHandler(w http.ResponseWriter, r *http.Request)

GetMCPSettingsHandler handles GET /api/settings/mcp

func GetSettingsHandler

func GetSettingsHandler(w http.ResponseWriter, r *http.Request)

GetSettingsHandler handles GET /api/settings/config

func GetSetupStatusHandler added in v1.0.7

func GetSetupStatusHandler(w http.ResponseWriter, r *http.Request)

GetSetupStatusHandler handles GET /api/settings/status

func HandleChat

func HandleChat(w http.ResponseWriter, r *http.Request)

HandleChat handles the /api/chat endpoint with SSE streaming

func InitToolsCache

func InitToolsCache(ctx context.Context)

InitToolsCache initializes the tools cache at server startup

func ListAgentsHandler

func ListAgentsHandler(w http.ResponseWriter, r *http.Request)

ListAgentsHandler handles GET /api/agents

func ListProviderModelsHandler

func ListProviderModelsHandler(w http.ResponseWriter, r *http.Request)

ListProviderModelsHandler handles GET /api/providers/{providerId}/models

func ListToolsHandler

func ListToolsHandler(w http.ResponseWriter, r *http.Request)

ListToolsHandler handles GET /api/tools

func RefreshToolsCache

func RefreshToolsCache(ctx context.Context)

RefreshToolsCache forces a refresh of the tools cache

func RegisterRoutes

func RegisterRoutes(router *mux.Router)

RegisterRoutes registers the API routes on a router

func SaveAgentHandler

func SaveAgentHandler(w http.ResponseWriter, r *http.Request)

SaveAgentHandler handles PUT /api/agents/{name}

func SendErrorSSE

func SendErrorSSE(w io.Writer, flusher http.Flusher, msg string)

SendErrorSSE sends an error event

func SendSSE

func SendSSE(w io.Writer, flusher http.Flusher, eventType string, data interface{})

SendSSE sends a Server-Sent Event

func UpdateMCPSettingsHandler

func UpdateMCPSettingsHandler(w http.ResponseWriter, r *http.Request)

UpdateMCPSettingsHandler handles PUT /api/settings/mcp

func UpdateSettingsHandler

func UpdateSettingsHandler(w http.ResponseWriter, r *http.Request)

UpdateSettingsHandler handles PUT /api/settings/config

Types

type AIChatRequest

type AIChatRequest struct {
	Message       string        `json:"message"`
	Context       string        `json:"context"`       // "create_flow" | "modify_nodes" | "node_config"
	CurrentYAML   string        `json:"currentYaml"`   // Current flow state
	SelectedNodes []string      `json:"selectedNodes"` // For node operations
	History       []ChatMessage `json:"history"`       // Conversation history
}

AIChatRequest is the request body for AI chat

type AIChatResponse

type AIChatResponse struct {
	Message      string `json:"message"`      // AI response text
	ProposedYAML string `json:"proposedYaml"` // Generated/modified YAML (if any)
	Action       string `json:"action"`       // "preview" | "apply" | "info"
	Error        string `json:"error,omitempty"`
}

AIChatResponse is the response from AI chat

type AgentDetailResponse

type AgentDetailResponse struct {
	Name   string              `json:"name"`
	Source string              `json:"source"`
	YAML   string              `json:"yaml"`
	Config *config.AgentConfig `json:"config,omitempty"`
}

AgentDetailResponse is the response for GET /api/agents/:name

type AgentListItem

type AgentListItem struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	Description string `json:"description"`
	Source      string `json:"source"` // "system" or "local"
}

AgentListItem represents an agent in the list response

type AgentListResponse

type AgentListResponse struct {
	Agents []AgentListItem `json:"agents"`
}

AgentListResponse is the response for GET /api/agents

type AppSettingsResponse

type AppSettingsResponse struct {
	General   GeneralSettings    `json:"general"`
	Providers []ProviderSettings `json:"providers"`
}

AppSettingsResponse is the response for GET /api/settings/config

type ChatMessage

type ChatMessage struct {
	Role    string `json:"role"` // "user" | "assistant"
	Content string `json:"content"`
}

ChatMessage represents a message in the conversation

type ChatRequest

type ChatRequest struct {
	AgentID   string `json:"agentId"`
	Message   string `json:"message"` // User input
	SessionID string `json:"sessionId"`
	Provider  string `json:"provider,omitempty"`
	Model     string `json:"model,omitempty"`
}

ChatRequest represents the request body for /api/chat

type FlowValidationResult

type FlowValidationResult struct {
	Valid  bool
	Errors []string
}

FlowValidationResult contains the result of validating a flow YAML

func ValidateFlowYAML

func ValidateFlowYAML(yamlStr string, availableTools []ToolInfo) FlowValidationResult

ValidateFlowYAML validates the generated flow YAML against the schema rules

type GeneralSettings

type GeneralSettings struct {
	DefaultProvider            string `json:"default_provider"`
	DefaultProviderDisplayName string `json:"default_provider_display_name"`
	DefaultModel               string `json:"default_model"`
}

GeneralSettings represents the general app settings

type ProviderSettings

type ProviderSettings struct {
	Name        string            `json:"name"`
	DisplayName string            `json:"display_name"`
	Configured  bool              `json:"configured"`
	Fields      map[string]string `json:"fields"` // Masked values for display
}

ProviderSettings represents a provider's configuration (masked)

type SessionManager

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

SessionManager manages active sessions

func GetSessionManager

func GetSessionManager() *SessionManager

GetSessionManager returns the singleton session manager

type SetupStatusResponse added in v1.0.7

type SetupStatusResponse struct {
	SetupRequired       bool     `json:"setupRequired"`
	HasDefaultProvider  bool     `json:"hasDefaultProvider"`
	HasDefaultModel     bool     `json:"hasDefaultModel"`
	ConfiguredProviders []string `json:"configuredProviders"`
}

SetupStatusResponse represents the setup status for the wizard

type ToolInfo

type ToolInfo struct {
	Name        string `json:"name"`
	Description string `json:"description"`
	Source      string `json:"source"` // "internal" or MCP server name
}

ToolInfo represents a tool in the list response

func GetCachedTools

func GetCachedTools() []ToolInfo

GetCachedTools returns the cached tools list

type ToolsCache

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

ToolsCache holds cached tool information to avoid re-initializing MCP on every request

type ToolsListResponse

type ToolsListResponse struct {
	Tools []ToolInfo `json:"tools"`
}

ToolsListResponse is the response for GET /api/tools

type UpdateAppSettingsRequest

type UpdateAppSettingsRequest struct {
	General   *GeneralSettings             `json:"general,omitempty"`
	Providers map[string]map[string]string `json:"providers,omitempty"`
}

UpdateAppSettingsRequest is the request for PUT /api/settings/config

Jump to

Keyboard shortcuts

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