Documentation
¶
Index ¶
- Constants
- Variables
- type ACPRuntimeCloser
- type ExportOptions
- type ExportRequest
- type ImportMode
- type ImportOptions
- type ImportResult
- type ImportStrategy
- type Manifest
- type ManifestEntry
- type ManifestOptions
- type Params
- type PreviewResult
- type ProfilePreview
- type RestorePlan
- type Section
- type SectionSummary
- type Service
- func (s *Service) Export(ctx context.Context, botID string, opts ExportOptions, dst io.Writer) error
- func (s *Service) Import(ctx context.Context, actorUserID string, raw []byte, opts ImportOptions, ...) (ImportResult, error)
- func (s *Service) Preview(ctx context.Context, raw []byte, opts ImportOptions, passphrase string) (PreviewResult, error)
- func (s *Service) Summary(ctx context.Context, botID string) (SummaryResult, error)
- type SummaryResult
- type WorkspaceData
Constants ¶
const ( BackupSchemaVersion = 1 ManifestPath = "manifest.json" )
Variables ¶
var AllExportSections = []Section{ SectionSettings, SectionModels, SectionACL, SectionChannels, SectionMCP, SectionSchedules, SectionEmail, SectionHistory, SectionAssets, SectionWorkspace, }
AllExportSections lists the sections a backup can contain, in display order. profile is always exported (it identifies the bot) and is not user-toggleable.
ErrHistoryResetUnavailable means an overwrite that can invalidate ACP state could not acquire the mandatory distributed runtime-reset boundary.
Functions ¶
This section is empty.
Types ¶
type ACPRuntimeCloser ¶
type ExportOptions ¶
type ExportOptions struct {
// Sections lists which sections to include. nil/empty ⇒ all sections.
// profile is always exported regardless.
Sections []Section `json:"sections,omitempty"`
}
func NormalizeExportOptions ¶
func NormalizeExportOptions(opts ExportOptions) ExportOptions
type ExportRequest ¶
type ExportRequest struct {
Sections []Section `json:"sections,omitempty"`
Passphrase string `json:"passphrase,omitempty"`
}
ExportRequest is the export endpoint body. Passphrase is kept out of ExportOptions on purpose so it can never leak into the bundle manifest: when set, the resulting bundle is encrypted with it.
type ImportMode ¶
type ImportMode string
const ( ImportModeCreate ImportMode = "create" ImportModeOverwrite ImportMode = "overwrite" )
type ImportOptions ¶
type ImportOptions struct {
Mode ImportMode `json:"mode,omitempty"`
TargetBotID string `json:"target_bot_id,omitempty"`
// Sections maps a section to its import strategy (skip|merge|replace).
// nil ⇒ every section imported with the default (merge). A section absent
// from a non-nil map, or mapped to "skip", is not imported.
Sections map[Section]ImportStrategy `json:"sections,omitempty"`
}
type ImportResult ¶
type ImportStrategy ¶
type ImportStrategy string
ImportStrategy controls how a section is applied to the target bot on import.
const ( StrategySkip ImportStrategy = "skip" StrategyMerge ImportStrategy = "merge" StrategyReplace ImportStrategy = "replace" )
type Manifest ¶
type Manifest struct {
SchemaVersion int `json:"schema_version"`
App string `json:"app"`
ExportedAt time.Time `json:"exported_at"`
SourceBotID string `json:"source_bot_id"`
SourceBotName string `json:"source_bot_name"`
Options ManifestOptions `json:"options"`
Entries []ManifestEntry `json:"entries"`
Warnings []string `json:"warnings,omitempty"`
Checksums map[string]string `json:"checksums,omitempty"`
}
type ManifestEntry ¶
type ManifestOptions ¶
type ManifestOptions struct {
Sections []Section `json:"sections,omitempty"`
}
type Params ¶
type Params struct {
Logger *slog.Logger
DB *pgxpool.Pool
Queries dbstore.Queries
Bots *bots.Service
Settings *settings.Service
ACL *acl.Service
Channels *channel.Store
MCP *mcp.ConnectionService
Schedules *schedule.Service
Email *emailpkg.Service
Providers *providerpkg.Service
Models *modelpkg.Service
SearchProviders *searchpkg.Service
FetchProviders *fetchpkg.Service
MemoryProviders *memprovider.Service
Workspace WorkspaceData
ACPRuntimes ACPRuntimeCloser
Workdirs dbstore.BotWorkdirStore
}
type PreviewResult ¶
type PreviewResult struct {
Manifest Manifest `json:"manifest"`
Profile *ProfilePreview `json:"profile,omitempty"`
Conflicts []string `json:"conflicts"`
Missing []string `json:"missing"`
Warnings []string `json:"warnings"`
Sections []SectionSummary `json:"sections"`
RestorePlan RestorePlan `json:"restore_plan"`
// Encrypted reports that the uploaded bundle is passphrase-encrypted. When
// true and no (or a wrong) passphrase was supplied, the other fields are
// empty and the UI should prompt for the passphrase. RequiresPassphrase
// distinguishes "needs a passphrase" from "passphrase was wrong".
Encrypted bool `json:"encrypted"`
RequiresPassphrase bool `json:"requires_passphrase"`
}
type ProfilePreview ¶
type ProfilePreview struct {
DisplayName string `json:"display_name"`
AvatarURL string `json:"avatar_url"`
Timezone string `json:"timezone"`
IsActive bool `json:"is_active"`
}
ProfilePreview surfaces the backup's bot identity so the UI can show an avatar + name card before importing.
type RestorePlan ¶
type Section ¶
type Section string
Section identifies a selectable group of data within a backup. On import, each section can be individually included or skipped. The bot profile is always imported (it creates or updates the bot itself) and is not a section.
const ( SectionProfile Section = "profile" SectionSettings Section = "settings" SectionModels Section = "models" SectionACL Section = "acl" SectionChannels Section = "channels" SectionMCP Section = "mcp" SectionSchedules Section = "schedules" SectionEmail Section = "email" SectionHistory Section = "history" SectionAssets Section = "assets" SectionWorkspace Section = "workspace" )
type SectionSummary ¶
type SectionSummary struct {
Key Section `json:"key"`
Count int `json:"count"`
TargetCount int `json:"target_count"`
Conflict bool `json:"conflict"`
Sensitive bool `json:"sensitive"`
Items []string `json:"items,omitempty"`
}
SectionSummary reports a restorable section, how many items it holds, and (in overwrite mode) how many the target already has. Items lists a sample of the contained item labels for an expandable detail view.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func (*Service) Import ¶
func (s *Service) Import(ctx context.Context, actorUserID string, raw []byte, opts ImportOptions, passphrase string) (ImportResult, error)
func (*Service) Preview ¶
func (s *Service) Preview(ctx context.Context, raw []byte, opts ImportOptions, passphrase string) (PreviewResult, error)
func (*Service) Summary ¶
Summary reports what a live bot would export: per-section item counts and a sample of item labels. It powers the export dialog so users see counts and details (and skip empty sections) before exporting. Unlike Export it does not pause the bot or stream the workspace, and it counts history/assets/workspace without loading them in full.
type SummaryResult ¶
type SummaryResult struct {
Profile *ProfilePreview `json:"profile,omitempty"`
Sections []SectionSummary `json:"sections"`
}
SummaryResult describes what a live bot would export, for the export dialog.
type WorkspaceData ¶
type WorkspaceData interface {
ExportData(ctx context.Context, botID string) (io.ReadCloser, error)
ImportData(ctx context.Context, botID string, r io.Reader) error
// CountData returns the number of files in the bot's workspace /data. It is
// best-effort context for the export dialog; an error means "unknown".
CountData(ctx context.Context, botID string) (int, error)
}