// Code generated by internal/schemagen. DO NOT EDIT.

package schema

import (
	"encoding/json"
	"fmt"
)

// Information about a command
// AvailableCommand represents a [schema] type.
type AvailableCommand struct {
	// The _meta property is reserved by ACP to allow clients and agents to attach additional
	Meta Meta `json:"_meta,omitempty"`
	// Human-readable description of what the command does
	Description string `json:"description"`
	// Input for the command if required
	Input *AvailableCommandInput `json:"input,omitempty"`
	// Command name (e.g., `create_plan`, `research_codebase`)
	Name string `json:"name"`
}

// The input specification for a command
// TypeAvailableCommandInputKind defines the values for TypeAvailableCommandInputKind.
type TypeAvailableCommandInputKind string

const (
	TypeAvailableCommandInputKindUnstructuredCommandInput TypeAvailableCommandInputKind = "unstructured"
)

// AvailableCommandInput is a discriminated union.
type AvailableCommandInput struct {
	Type                     TypeAvailableCommandInputKind `json:"type"`
	UnstructuredCommandInput *UnstructuredCommandInput     `json:"-"`
}

func (u AvailableCommandInput) MarshalJSON() ([]byte, error) {
	switch u.Type {
	case TypeAvailableCommandInputKindUnstructuredCommandInput:
		return marshalWith(u.UnstructuredCommandInput, "type", "unstructured")
	default:
		return json.Marshal(map[string]TypeAvailableCommandInputKind{"type": u.Type})
	}
}

func (u *AvailableCommandInput) UnmarshalJSON(data []byte) error {
	var raw map[string]json.RawMessage
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}
	discrim, ok := raw["type"]
	if !ok {
		return fmt.Errorf("missing type field")
	}
	var dv string
	if err := json.Unmarshal(discrim, &dv); err != nil {
		return err
	}
	u.Type = TypeAvailableCommandInputKind(dv)
	switch u.Type {
	case TypeAvailableCommandInputKindUnstructuredCommandInput:
		u.UnstructuredCommandInput = &UnstructuredCommandInput{}
		return json.Unmarshal(data, u.UnstructuredCommandInput)
	default:
		return nil
	}
}

// Available commands are ready or have changed
// AvailableCommandsUpdate represents a [schema] type.
type AvailableCommandsUpdate struct {
	// The _meta property is reserved by ACP to allow clients and agents to attach additional
	Meta Meta `json:"_meta,omitempty"`
	// Commands the agent can execute
	AvailableCommands []*AvailableCommand `json:"availableCommands"`
}

// Session configuration options have been updated
// ConfigOptionUpdate represents a [schema] type.
type ConfigOptionUpdate struct {
	// The _meta property is reserved by ACP to allow clients and agents to attach additional
	Meta Meta `json:"_meta,omitempty"`
	// The full set of configuration options and their current values
	ConfigOptions []*SessionConfigOption `json:"configOptions"`
}

// A streamed item of content
// ContentChunk represents a [schema] type.
type ContentChunk struct {
	// The _meta property is reserved by ACP to allow clients and agents to attach additional
	Meta Meta `json:"_meta,omitempty"`
	// A single item of content
	Content *ContentBlock `json:"content"`
}

// The current mode of the session has changed
// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
// CurrentModeUpdate represents a [schema] type.
type CurrentModeUpdate struct {
	// The _meta property is reserved by ACP to allow clients and agents to attach additional
	Meta Meta `json:"_meta,omitempty"`
	// The ID of the current mode
	CurrentModeId *SessionModeId `json:"currentModeId"`
}

// An execution plan for accomplishing complex tasks.
// Plans consist of multiple entries representing individual tasks or goals.
// Agents report plans to clients to provide visibility into their execution strategy.
// Plans can evolve during execution as the agent discovers new requirements or completes tasks.
// See protocol docs: [Agent Plan](https://agentclientprotocol.com/protocol/agent-plan)
// Plan represents a [schema] type.
type Plan struct {
	// The _meta property is reserved by ACP to allow clients and agents to attach additional
	Meta Meta `json:"_meta,omitempty"`
	// The list of tasks to be accomplished
	Entries []*PlanEntry `json:"entries"`
}

// A single entry in the execution plan.
// Represents a task or goal that the assistant intends to accomplish
// as part of fulfilling the user's request.
// See protocol docs: [Plan Entries](https://agentclientprotocol.com/protocol/agent-plan#plan-entries)
// PlanEntry represents a [schema] type.
type PlanEntry struct {
	// The _meta property is reserved by ACP to allow clients and agents to attach additional
	Meta Meta `json:"_meta,omitempty"`
	// Human-readable description of what this task aims to accomplish
	Content string `json:"content"`
	// The relative importance of this task
	Priority *PlanEntryPriority `json:"priority"`
	// Current execution status of this task
	Status *PlanEntryStatus `json:"status"`
}

// A group of possible values for a session configuration option
// SessionConfigSelectGroup represents a [schema] type.
type SessionConfigSelectGroup struct {
	// The _meta property is reserved by ACP to allow clients and agents to attach additional
	Meta Meta `json:"_meta,omitempty"`
	// Unique identifier for this group
	Group *SessionConfigGroupId `json:"group"`
	// Human-readable label for this group
	Name string `json:"name"`
	// The set of option values in this group
	Options []*SessionConfigSelectOption `json:"options"`
}

// A possible value for a session configuration option
// SessionConfigSelectOption represents a [schema] type.
type SessionConfigSelectOption struct {
	// The _meta property is reserved by ACP to allow clients and agents to attach additional
	Meta Meta `json:"_meta,omitempty"`
	// Optional description for this option value
	Description *string `json:"description,omitempty"`
	// Human-readable label for this option value
	Name string `json:"name"`
	// Unique identifier for this option value
	Value *SessionConfigValueId `json:"value"`
}

// Update to session metadata. All fields are optional to support partial updates.
// Agents send this notification to update session information like title or custom metadata.
// This allows clients to display dynamic session names and track session state changes
// SessionInfoUpdate represents a [schema] type.
type SessionInfoUpdate struct {
	// The _meta property is reserved by ACP to allow clients and agents to attach additional
	Meta Meta `json:"_meta,omitempty"`
	// Human-readable title for the session. Set to null to clear
	Title *string `json:"title,omitempty"`
	// ISO 8601 timestamp of last activity. Set to null to clear
	UpdatedAt *string `json:"updatedAt,omitempty"`
}

// A mode the agent can operate in.
// See protocol docs: [Session Modes](https://agentclientprotocol.com/protocol/session-modes)
// SessionMode represents a [schema] type.
type SessionMode struct {
	// The _meta property is reserved by ACP to allow clients and agents to attach additional
	Meta        Meta           `json:"_meta,omitempty"`
	Description *string        `json:"description,omitempty"`
	Id          *SessionModeId `json:"id"`
	Name        string         `json:"name"`
}

// The set of modes and the one currently active
// SessionModeState represents a [schema] type.
type SessionModeState struct {
	// The _meta property is reserved by ACP to allow clients and agents to attach additional
	Meta Meta `json:"_meta,omitempty"`
	// The set of modes that the Agent can operate in
	AvailableModes []*SessionMode `json:"availableModes"`
	// The current mode the Agent is in
	CurrentModeId *SessionModeId `json:"currentModeId"`
}

// Different types of updates that can be sent during session processing.
// These updates provide real-time feedback about the agent's progress.
// See protocol docs: [Agent Reports Output](https://agentclientprotocol.com/protocol/prompt-turn#3-agent-reports-output)
// SessionUpdateKind defines the values for SessionUpdateKind.
type SessionUpdateKind string

const (
	SessionUpdateKindAgentMessageChunk       SessionUpdateKind = "agent_message_chunk"
	SessionUpdateKindAgentThoughtChunk       SessionUpdateKind = "agent_thought_chunk"
	SessionUpdateKindAvailableCommandsUpdate SessionUpdateKind = "available_commands_update"
	SessionUpdateKindConfigOptionUpdate      SessionUpdateKind = "config_option_update"
	SessionUpdateKindCurrentModeUpdate       SessionUpdateKind = "current_mode_update"
	SessionUpdateKindPlan                    SessionUpdateKind = "plan"
	SessionUpdateKindSessionInfoUpdate       SessionUpdateKind = "session_info_update"
	SessionUpdateKindToolCall                SessionUpdateKind = "tool_call"
	SessionUpdateKindToolCallUpdate          SessionUpdateKind = "tool_call_update"
	SessionUpdateKindUserMessageChunk        SessionUpdateKind = "user_message_chunk"
)

// SessionUpdate is a discriminated union.
type SessionUpdate struct {
	SessionUpdate           SessionUpdateKind        `json:"sessionUpdate"`
	UserMessageChunk        *ContentChunk            `json:"-"`
	AgentMessageChunk       *ContentChunk            `json:"-"`
	AgentThoughtChunk       *ContentChunk            `json:"-"`
	ToolCall                *ToolCall                `json:"-"`
	ToolCallUpdate          *ToolCallUpdate          `json:"-"`
	Plan                    *Plan                    `json:"-"`
	AvailableCommandsUpdate *AvailableCommandsUpdate `json:"-"`
	CurrentModeUpdate       *CurrentModeUpdate       `json:"-"`
	ConfigOptionUpdate      *ConfigOptionUpdate      `json:"-"`
	SessionInfoUpdate       *SessionInfoUpdate       `json:"-"`
}

func (u SessionUpdate) MarshalJSON() ([]byte, error) {
	switch u.SessionUpdate {
	case SessionUpdateKindAgentMessageChunk:
		return marshalWith(u.AgentMessageChunk, "sessionUpdate", "agent_message_chunk")
	case SessionUpdateKindAgentThoughtChunk:
		return marshalWith(u.AgentThoughtChunk, "sessionUpdate", "agent_thought_chunk")
	case SessionUpdateKindAvailableCommandsUpdate:
		return marshalWith(u.AvailableCommandsUpdate, "sessionUpdate", "available_commands_update")
	case SessionUpdateKindConfigOptionUpdate:
		return marshalWith(u.ConfigOptionUpdate, "sessionUpdate", "config_option_update")
	case SessionUpdateKindCurrentModeUpdate:
		return marshalWith(u.CurrentModeUpdate, "sessionUpdate", "current_mode_update")
	case SessionUpdateKindPlan:
		return marshalWith(u.Plan, "sessionUpdate", "plan")
	case SessionUpdateKindSessionInfoUpdate:
		return marshalWith(u.SessionInfoUpdate, "sessionUpdate", "session_info_update")
	case SessionUpdateKindToolCall:
		return marshalWith(u.ToolCall, "sessionUpdate", "tool_call")
	case SessionUpdateKindToolCallUpdate:
		return marshalWith(u.ToolCallUpdate, "sessionUpdate", "tool_call_update")
	case SessionUpdateKindUserMessageChunk:
		return marshalWith(u.UserMessageChunk, "sessionUpdate", "user_message_chunk")
	default:
		return json.Marshal(map[string]SessionUpdateKind{"sessionUpdate": u.SessionUpdate})
	}
}

func (u *SessionUpdate) UnmarshalJSON(data []byte) error {
	var raw map[string]json.RawMessage
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}
	discrim, ok := raw["sessionUpdate"]
	if !ok {
		return fmt.Errorf("missing sessionUpdate field")
	}
	var dv string
	if err := json.Unmarshal(discrim, &dv); err != nil {
		return err
	}
	u.SessionUpdate = SessionUpdateKind(dv)
	switch u.SessionUpdate {
	case SessionUpdateKindAgentMessageChunk:
		u.AgentMessageChunk = &ContentChunk{}
		return json.Unmarshal(data, u.AgentMessageChunk)
	case SessionUpdateKindAgentThoughtChunk:
		u.AgentThoughtChunk = &ContentChunk{}
		return json.Unmarshal(data, u.AgentThoughtChunk)
	case SessionUpdateKindAvailableCommandsUpdate:
		u.AvailableCommandsUpdate = &AvailableCommandsUpdate{}
		return json.Unmarshal(data, u.AvailableCommandsUpdate)
	case SessionUpdateKindConfigOptionUpdate:
		u.ConfigOptionUpdate = &ConfigOptionUpdate{}
		return json.Unmarshal(data, u.ConfigOptionUpdate)
	case SessionUpdateKindCurrentModeUpdate:
		u.CurrentModeUpdate = &CurrentModeUpdate{}
		return json.Unmarshal(data, u.CurrentModeUpdate)
	case SessionUpdateKindPlan:
		u.Plan = &Plan{}
		return json.Unmarshal(data, u.Plan)
	case SessionUpdateKindSessionInfoUpdate:
		u.SessionInfoUpdate = &SessionInfoUpdate{}
		return json.Unmarshal(data, u.SessionInfoUpdate)
	case SessionUpdateKindToolCall:
		u.ToolCall = &ToolCall{}
		return json.Unmarshal(data, u.ToolCall)
	case SessionUpdateKindToolCallUpdate:
		u.ToolCallUpdate = &ToolCallUpdate{}
		return json.Unmarshal(data, u.ToolCallUpdate)
	case SessionUpdateKindUserMessageChunk:
		u.UserMessageChunk = &ContentChunk{}
		return json.Unmarshal(data, u.UserMessageChunk)
	default:
		return nil
	}
}
